├── .gitattributes ├── .gitignore ├── build ├── FirmwareBundles │ ├── iPhone5,2_8.4.1_12H321.bundle │ │ ├── Info.plist │ │ ├── asr.patch │ │ ├── fstab.patch │ │ ├── iBEC.n42.RELEASE.patch │ │ └── iBSS.n42.RELEASE.patch │ └── iPod5,1_8.4.1_12H321_dec.bundle │ │ ├── Info.plist │ │ ├── asr.patch │ │ ├── fstab.patch │ │ ├── iBEC.n78.RELEASE.patch │ │ ├── iBEC.n78.RELEASE.patch2 │ │ └── iBSS.n78.RELEASE.patch ├── idevicererestore ├── idevicerestore ├── ipsw └── src │ ├── bin.tar │ └── daibutsu │ ├── cydia.tar │ ├── reboot_n42.sh │ ├── reboot_n78.sh │ └── untether.tar ├── readme.md └── src ├── daibutsu └── dyld │ └── haxx_overwrite.c ├── idevicererestore ├── asr.c ├── asr.h ├── common.c ├── common.h ├── dfu.c ├── dfu.h ├── digest.h ├── download.c ├── download.h ├── endianness.h ├── fdr.c ├── fdr.h ├── fls.c ├── fls.h ├── globals.h ├── idevicerestore.c ├── idevicerestore.h ├── img3.c ├── img3.h ├── img4.c ├── img4.h ├── ipsw.c ├── ipsw.h ├── locking.c ├── locking.h ├── mbn.c ├── mbn.h ├── normal.c ├── normal.h ├── partial.c ├── partial.h ├── recovery.c ├── recovery.h ├── restore.c ├── restore.h ├── socket.c ├── socket.h ├── thread.c ├── thread.h ├── tss.c ├── tss.h └── ubid_list.h └── xpwn ├── common ├── abstractfile.c └── base64.c ├── dmg ├── checksum.c ├── dmgfile.c ├── dmglib.c ├── filevault.c ├── io.c ├── partition.c ├── resources.c └── udif.c ├── hdutil └── hdutil.c ├── hfs ├── btree.c ├── catalog.c ├── extents.c ├── fastunicodecompare.c ├── flatfile.c ├── hfs.c ├── hfscompress.c ├── hfslib.c ├── rawfile.c ├── utility.c ├── volume.c └── xattr.c ├── include ├── abstractfile.h ├── common.h ├── dmg │ ├── dmg.h │ ├── dmgfile.h │ ├── dmglib.h │ └── filevault.h ├── hfs │ ├── hfscompress.h │ ├── hfslib.h │ └── hfsplus.h ├── partial │ ├── firmwaremaster.h │ └── partial.h ├── pref.h └── xpwn │ ├── 8900.h │ ├── ibootim.h │ ├── img2.h │ ├── img3.h │ ├── libxpwn.h │ ├── lzss.h │ ├── lzssfile.h │ ├── nor_files.h │ ├── outputstate.h │ ├── plist.h │ └── pwnutil.h ├── ipsw-patch ├── 8900.c ├── bspatch.c ├── ibootim.c ├── imagetool.c ├── img2.c ├── img3.c ├── itunespwn.c ├── libxpwn.c ├── lzss.c ├── lzssfile.c ├── main.c ├── nor_files.c ├── outputstate.c ├── plist.c ├── pwnutil.c ├── ticket.c ├── validate.c ├── validate_ca.h └── xpwntool.c └── minizip ├── crypt.h ├── ioapi.c ├── ioapi.h ├── miniunz.c ├── minizip.c ├── mztools.c ├── mztools.h ├── unzip.c ├── unzip.h ├── zip.c └── zip.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.bin 3 | *.a 4 | *.shsh 5 | *.ipsw -------------------------------------------------------------------------------- /build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RootFilesystem 6 | 058-24110-023.dmg 7 | RootFilesystemSize 8 | 2058 9 | Filename 10 | iPhone5,2_8.4.1_12H321_Restore.ipsw 11 | Name 12 | iPhone5,2_8.4.1_12H321 13 | hwmodel 14 | N42 15 | RamdiskMountVolume 16 | ramdisk 17 | SubPlatform 18 | 6 19 | Platform 20 | 1 21 | RamdiskOptionsPath 22 | /usr/local/share/restore/options.n42.plist 23 | SHA1 24 | da4e50bf721d91bbd0b4a90ba9df9cdf2e8b9f53 25 | RamdiskPatches 26 | 27 | asr 28 | 29 | File 30 | usr/sbin/asr 31 | Patch 32 | asr.patch 33 | 34 | 35 | DownloadUrl 36 | 37 | FilesystemPatches 38 | 39 | Filesystem Jailbreak 40 | 41 | 42 | Action 43 | Patch 44 | File 45 | etc/fstab 46 | Name 47 | Remove nosuid and nodev from /private/var 48 | Patch 49 | fstab.patch 50 | 51 | 52 | 53 | RootFilesystemMountVolume 54 | Donner12H321.N42OS 55 | FirmwarePatches 56 | 57 | iBSS 58 | 59 | File 60 | Firmware/dfu/iBSS.n42.RELEASE.dfu 61 | Key 62 | 74cd68729b800a20b1f8e8a3cb5517024a09f074eaa05b099db530fb5783275e 63 | Patch 64 | iBSS.n42.RELEASE.patch 65 | IV 66 | fdad2b7a35384fa2ffc7221213ca1082 67 | TypeFlag 68 | 8 69 | 70 | iBEC 71 | 72 | File 73 | Firmware/dfu/iBEC.n42.RELEASE.dfu 74 | Key 75 | 888f24c26a13fdb2c8182b156d793b1350428e2b6c31a634d16a61752b236dc9 76 | Patch 77 | iBEC.n42.RELEASE.patch 78 | IV 79 | ba178c287f6ce38acbec569f6adbf170 80 | TypeFlag 81 | 8 82 | 83 | Restore Ramdisk 84 | 85 | File 86 | 058-23947-023.dmg 87 | Key 88 | 9bde35e15c13939b0e910e30f45109103cacabc3c5535a20a79f87d35d4a8c35 89 | TypeFlag 90 | 8 91 | IV 92 | 9f3c9ed053e2057f7b2be54a80c3eec8 93 | 94 | 95 | RootFilesystemKey 96 | 7f68bec2637d5ac0837e38878a8a411c72131fc6394b5a84fd0f878f54f97af3801f34fd 97 | needPref 98 | 99 | PackagePath 100 | src/daibutsu/cydia.tar 101 | UntetherPath 102 | src/daibutsu/untether.tar 103 | RamdiskPackage 104 | src/bin.tar 105 | RamdiskReboot 106 | src/daibutsu/reboot_n42.sh 107 | 108 | 109 | -------------------------------------------------------------------------------- /build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/asr.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/asr.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/fstab.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/fstab.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/iBEC.n42.RELEASE.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/iBEC.n42.RELEASE.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/iBSS.n42.RELEASE.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPhone5,2_8.4.1_12H321.bundle/iBSS.n42.RELEASE.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RootFilesystem 6 | 058-24051-023.dmg 7 | RootFilesystemSize 8 | 2048 9 | Filename 10 | iPod5,1_8.4.1_12H321_Restore.ipsw 11 | RamdiskMountVolume 12 | ramdisk 13 | Name 14 | iPod5,1_8.4.1_12H321 15 | hwmodel 16 | N78 17 | SubPlatform 18 | 6 19 | Platform 20 | 1 21 | RamdiskOptionsPath 22 | /usr/local/share/restore/options.n78.plist 23 | SHA1 24 | cc08267089f5294884a7bfec8bb10dcb197fc20a 25 | RamdiskPatches 26 | 27 | asr 28 | 29 | File 30 | usr/sbin/asr 31 | Patch 32 | asr.patch 33 | 34 | 35 | DownloadUrl 36 | 37 | FilesystemPatches 38 | 39 | Filesystem Jailbreak 40 | 41 | 42 | Action 43 | Patch 44 | File 45 | etc/fstab 46 | Name 47 | Remove nosuid and nodev from /private/var 48 | Patch 49 | fstab.patch 50 | 51 | 52 | 53 | RootFilesystemMountVolume 54 | Donner12H321.N78OS 55 | FirmwarePatches 56 | 57 | iBSS 58 | 59 | File 60 | Firmware/dfu/iBSS.n78.RELEASE.dfu 61 | Key 62 | 0a0e0aedc8171669c9af6a229930a395959df55dcd8a3ee1fe0f4c009007df3c 63 | Decrypt 64 | 65 | Patch 66 | iBSS.n78.RELEASE.patch 67 | IV 68 | e0175b03bc29817adc312638884e0898 69 | TypeFlag 70 | 8 71 | 72 | iBEC 73 | 74 | File 75 | Firmware/dfu/iBEC.n78.RELEASE.dfu 76 | Key 77 | 5fac4cdeac38c7fbc19f6c2be83eabdcea7fe0ae7f57cf9a70182cc9cad8209f 78 | Decrypt 79 | 80 | Patch 81 | iBEC.n78.RELEASE.patch 82 | IV 83 | ef80ca77212ebc1f823b15664076eb66 84 | TypeFlag 85 | 8 86 | 87 | Restore Ramdisk 88 | 89 | File 90 | 058-23992-023.dmg 91 | Key 92 | e3ddf7d357feb1f340a8ae23938468f50e071d2ec31d657816d08435cb7fdf14 93 | Decrypt 94 | 95 | TypeFlag 96 | 8 97 | IV 98 | 601d0a8aa1af6907a27f9680e5c7785d 99 | 100 | RestoreDeviceTree 101 | 102 | File 103 | Firmware/all_flash/all_flash.n78ap.production/DeviceTree.n78ap.img3 104 | Key 105 | 1e0ffa0989ca51c34f86964b7c9642436ad3071acfb5c877f3fc0e84cc7180b9 106 | DecryptPath 107 | Downgrade/DeviceTree.n78ap.img3 108 | IV 109 | 67b2dd2762aeacb6e3ea1fe0ec5ccda1 110 | 111 | RestoreLogo 112 | 113 | File 114 | Firmware/all_flash/all_flash.n78ap.production/applelogo@2x~iphone.s5l8942x.img3 115 | Key 116 | 636d92f146bde17843278ee1a35f512e3fcc65b91a9dbd686bdb947ca9e498dc 117 | DecryptPath 118 | Downgrade/applelogo@2x~iphone.s5l8942x.img3 119 | IV 120 | 4e4d5f6f690d61dbb0dc41faac09969d 121 | 122 | RestoreKernelCache 123 | 124 | File 125 | kernelcache.release.n78 126 | Key 127 | e7904495a19966d622389ce0e1113f4f00e0fc7c0fa65c4d66e79dd12450edf9 128 | DecryptPath 129 | Downgrade/kernelcache.release.n78 130 | IV 131 | c96b701e3dc9ae4d07bf722a4cb50011 132 | 133 | 134 | RootFilesystemKey 135 | d0efe3748387105f1851c6161abcddf3cdcde1e02052357116bc50149040d8c6b318b0a3 136 | needPref 137 | 138 | PackagePath 139 | src/daibutsu/cydia.tar 140 | UntetherPath 141 | src/daibutsu/untether.tar 142 | RamdiskPackage 143 | src/bin.tar 144 | RamdiskReboot 145 | src/daibutsu/reboot_n78.sh 146 | 147 | 148 | -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/asr.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/asr.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/fstab.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/fstab.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBEC.n78.RELEASE.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBEC.n78.RELEASE.patch -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBEC.n78.RELEASE.patch2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBEC.n78.RELEASE.patch2 -------------------------------------------------------------------------------- /build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBSS.n78.RELEASE.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/FirmwareBundles/iPod5,1_8.4.1_12H321_dec.bundle/iBSS.n78.RELEASE.patch -------------------------------------------------------------------------------- /build/idevicererestore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/idevicererestore -------------------------------------------------------------------------------- /build/idevicerestore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/idevicerestore -------------------------------------------------------------------------------- /build/ipsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/ipsw -------------------------------------------------------------------------------- /build/src/bin.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/src/bin.tar -------------------------------------------------------------------------------- /build/src/daibutsu/cydia.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/src/daibutsu/cydia.tar -------------------------------------------------------------------------------- /build/src/daibutsu/reboot_n42.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # mount fs as r/w 4 | mount_hfs /dev/disk0s1s1 /mnt1 5 | mount_hfs /dev/disk0s1s2 /mnt2 6 | 7 | # remove iboot haxx related nvram values 8 | nvram -d boot-partition 9 | nvram -d boot-ramdisk 10 | 11 | # dyld haxx 12 | /usr/bin/haxx_overwrite -n42 13 | -------------------------------------------------------------------------------- /build/src/daibutsu/reboot_n78.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # mount fs as r/w 4 | mount_hfs /dev/disk0s1s1 /mnt1 5 | mount_hfs /dev/disk0s1s2 /mnt2 6 | 7 | # remove iboot haxx related nvram values 8 | nvram -d boot-partition 9 | nvram -d boot-ramdisk 10 | 11 | # dyld haxx 12 | /usr/bin/haxx_overwrite -n78 13 | -------------------------------------------------------------------------------- /build/src/daibutsu/untether.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dora2ios/daibutsuCFW/a81d5b280535b3192784ba92c1336007709f1fb2/build/src/daibutsu/untether.tar -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # daibutsuCFW 2 | 3 | ## how to make custom firmware 4 | ``` 5 | ./ipsw -daibutsu [-memory] [-bbupdate] 6 | ``` 7 | 8 | ## how to restore with custom firmware 9 | For A5 devices, restore from `kDFU mode` or `pwned DFU mode` or `pwned Recovery Mode`. 10 | For A6 devices, restore from `pwned DFU mode` or `pwned Recovery Mode`. 11 | 12 | ### cmd 13 | ``` 14 | ./idevicererestore -b -r 15 | ``` 16 | 17 | ## references 18 | ### list of original keys in xpwn/ipsw-patch 19 | | key | type | description | 20 | |---------|----------|----------| 21 | | hwmodel | String (ex. `N42`) | Used to move the jetsamproperties daemon (com.apple.jetsamproperties.`XXX`.plist) for iOS 8 untether, such as daibutsu. | 22 | | needPref | Bool | Set SBShowNonDefaultSystemApps on SpringBoard. This is required to display the Non-Default apps on the home screen on some devices. | 23 | | PackagePath | String | This is the path to reference when incorporating package such as cydia into CFW. The format of the file must be tape archive. | 24 | | UntetherPath | String | This is the path to reference when incorporating untether package such as daibutsu into CFW. The format of the file must be tape archive. | 25 | | RamdiskPackage | String | This is the path to reference when incorporating package into RestoreRamdisk. The format of the file must be tape archive. | 26 | | RamdiskReboot | String | This is the path to refer to the file to replace the /sbin/reboot file on RestoreRamdisk. Replace the /sbin/reboot executable in RestoreRamdisk and perform any action after the restore. | 27 | 28 | ### list of flags and devices supported by haxx_overwrite (dyld haxx) 29 | | flag | device | 30 | |---------|----------| 31 | | `-n94` | iPhone 4S | 32 | | `-n42` | iPhone 5 [iPhone5,2] | 33 | | `-n78` | iPod touch 5th gen | 34 | | `-k93a` | iPad 2 [iPad2,4] | 35 | | `-p105` | iPad mini [iPad2,5] | 36 | | `-p106` | iPad mini [iPad2,6] | 37 | | `-p107` | iPad mini [iPad2,7] | 38 | | `-j1` | iPad 3rd gen [iPad3,1] | 39 | | `-j2` | iPad 3rd gen [iPad3,2] | 40 | | `-j2a` | iPad 3rd gen [iPad3,3] | 41 | -------------------------------------------------------------------------------- /src/idevicererestore/asr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * asr.h 3 | * Functions for handling asr connections 4 | * 5 | * Copyright (c) 2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_ASR_H 25 | #define IDEVICERESTORE_ASR_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | typedef void (*asr_progress_cb_t)(double, void*); 34 | 35 | struct asr_client { 36 | idevice_connection_t connection; 37 | uint8_t checksum_chunks; 38 | int lastprogress; 39 | asr_progress_cb_t progress_cb; 40 | void* progress_cb_data; 41 | }; 42 | typedef struct asr_client *asr_client_t; 43 | 44 | int asr_open_with_timeout(idevice_t device, asr_client_t* asr); 45 | void asr_set_progress_callback(asr_client_t asr, asr_progress_cb_t, void* userdata); 46 | int asr_send(asr_client_t asr, plist_t data); 47 | int asr_receive(asr_client_t asr, plist_t* data); 48 | int asr_send_buffer(asr_client_t asr, const char* data, uint32_t size); 49 | void asr_free(asr_client_t asr); 50 | int asr_perform_validation(asr_client_t asr, const char* filesystem); 51 | int asr_send_payload(asr_client_t asr, const char* filesystem); 52 | int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file); 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/idevicererestore/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * common.h 3 | * Misc functions used in idevicerestore 4 | * 5 | * Copyright (c) 2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_COMMON_H 25 | #define IDEVICERESTORE_COMMON_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #ifdef HAVE_CONFIG_H 32 | #include 33 | #endif 34 | 35 | #include 36 | #include 37 | 38 | #include "idevicerestore.h" 39 | 40 | #define MODE_UNKNOWN -1 41 | #define MODE_WTF 0 42 | #define MODE_DFU 1 43 | #define MODE_RECOVERY 2 44 | #define MODE_RESTORE 3 45 | #define MODE_NORMAL 4 46 | 47 | #define FLAG_QUIT 1 48 | 49 | #define CPFM_FLAG_SECURITY_MODE 1 << 0 50 | #define CPFM_FLAG_PRODUCTION_MODE 1 << 1 51 | 52 | #define IBOOT_FLAG_IMAGE4_AWARE 1 << 2 53 | #define IBOOT_FLAG_EFFECTIVE_SECURITY_MODE 1 << 3 54 | #define IBOOT_FLAG_EFFECTIVE_PRODUCTION_MODE 1 << 4 55 | 56 | struct dfu_client_t; 57 | struct normal_client_t; 58 | struct restore_client_t; 59 | struct recovery_client_t; 60 | 61 | struct idevicerestore_mode_t { 62 | int index; 63 | const char* string; 64 | }; 65 | 66 | struct idevicerestore_entry_t { 67 | char* name; 68 | char* path; 69 | char* filename; 70 | char* blob_data; 71 | uint32_t blob_size; 72 | struct idevicerestore_entry* next; 73 | struct idevicerestore_entry* prev; 74 | }; 75 | 76 | struct idevicerestore_client_t { 77 | char* bbfwtmp; 78 | int flags; 79 | char* otamanifest; 80 | plist_t tss; 81 | plist_t basebandBuildIdentity; 82 | char* tss_url; 83 | plist_t version_data; 84 | uint64_t ecid; 85 | unsigned char* nonce; 86 | int nonce_size; 87 | int image4supported; 88 | plist_t preflight_info; 89 | char* udid; 90 | char* srnm; 91 | char* ipsw; 92 | const char* filesystem; 93 | struct dfu_client_t* dfu; 94 | struct normal_client_t* normal; 95 | struct restore_client_t* restore; 96 | struct recovery_client_t* recovery; 97 | irecv_device_t device; 98 | struct idevicerestore_entry_t** entries; 99 | struct idevicerestore_mode_t* mode; 100 | char* version; 101 | char* build; 102 | int build_major; 103 | char* restore_boot_args; 104 | char* cache_dir; 105 | idevicerestore_progress_cb_t progress_cb; 106 | void* progress_cb_data; 107 | char *manifestPath; 108 | char *basebandPath; 109 | int isCustom; 110 | }; 111 | 112 | extern struct idevicerestore_mode_t idevicerestore_modes[]; 113 | 114 | extern int idevicerestore_debug; 115 | 116 | void info(const char* format, ...); 117 | void error(const char* format, ...); 118 | void debug(const char* format, ...); 119 | 120 | void debug_plist(plist_t plist); 121 | void print_progress_bar(double progress); 122 | int read_file(const char* filename, void** data, size_t* size); 123 | int write_file(const char* filename, const void* data, size_t size); 124 | 125 | char *generate_guid(void); 126 | 127 | #ifdef WIN32 128 | #include 129 | #define __mkdir(path, mode) mkdir(path) 130 | #define FMT_qu "%I64u" 131 | #ifndef sleep 132 | #define sleep(x) Sleep(x*1000) 133 | #endif 134 | #else 135 | #include 136 | #define __mkdir(path, mode) mkdir(path, mode) 137 | #define FMT_qu "%qu" 138 | #endif 139 | 140 | int mkdir_with_parents(const char *dir, int mode); 141 | 142 | void idevicerestore_progress(struct idevicerestore_client_t* client, int step, double progress); 143 | 144 | #ifndef HAVE_STRSEP 145 | char* strsep(char** strp, const char* delim); 146 | #endif 147 | 148 | #ifdef __cplusplus 149 | } 150 | #endif 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /src/idevicererestore/dfu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dfu.h 3 | * Functions for handling idevices in DFU mode 4 | * 5 | * Copyright (c) 2010-2013 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012-2015 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_DFU_H 25 | #define IDEVICERESTORE_DFU_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include "common.h" 33 | 34 | struct dfu_client_t { 35 | irecv_client_t client; 36 | const char* ipsw; 37 | plist_t tss; 38 | }; 39 | 40 | int dfu_client_new(struct idevicerestore_client_t* client); 41 | void dfu_client_free(struct idevicerestore_client_t* client); 42 | int dfu_check_mode(struct idevicerestore_client_t* client, int* mode); 43 | const char* dfu_check_hardware_model(struct idevicerestore_client_t* client); 44 | int dfu_send_buffer(struct idevicerestore_client_t* client, unsigned char* buffer, unsigned int size); 45 | int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component); 46 | int dfu_get_cpid(struct idevicerestore_client_t* client, unsigned int* cpid); 47 | int dfu_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); 48 | int dfu_is_image4_supported(struct idevicerestore_client_t* client); 49 | int dfu_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 50 | int dfu_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 51 | int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity); 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/idevicererestore/digest.h: -------------------------------------------------------------------------------- 1 | #ifndef DIGEST_H 2 | #define DIGEST_H 3 | 4 | // RestoreRamdisk digest 5 | unsigned char s5l8940x_841_rdsk_digest[] = { 6 | 0xe9, 0x84, 0xfc, 0x92, 7 | 0x66, 0x6d, 0xa3, 0xbe, 8 | 0x9b, 0x60, 0x62, 0x1a, 9 | 0xa6, 0x93, 0xa4, 0x72, 10 | 0xa8, 0x38, 0x82, 0xa8 11 | }; 12 | 13 | unsigned char s5l8942x_841_rdsk_digest[] = { 14 | 0x5b, 0x5b, 0x3d, 0x87, 15 | 0x4a, 0x3e, 0x3b, 0x23, 16 | 0x66, 0xfa, 0xcd, 0xdf, 17 | 0x07, 0x11, 0x50, 0x41, 18 | 0x1a, 0x0b, 0x35, 0xb0 19 | }; 20 | 21 | unsigned char s5l8945x_841_rdsk_digest[] = { 22 | 0x88, 0x80, 0x31, 0x85, 23 | 0x45, 0xea, 0x56, 0x6c, 24 | 0xfe, 0xe3, 0x86, 0x62, 25 | 0x3f, 0x4c, 0x10, 0x00, 26 | 0xd6, 0x1f, 0x34, 0x8f 27 | }; 28 | 29 | unsigned char s5l8950x_841_rdsk_digest[] = { 30 | 0x22, 0xc7, 0x1e, 0x79, 31 | 0x5a, 0x90, 0x08, 0xb0, 32 | 0x90, 0x3a, 0xe5, 0x58, 33 | 0x59, 0x14, 0x60, 0x87, 34 | 0x27, 0x0e, 0x00, 0x4f 35 | }; 36 | 37 | unsigned char s5l8955x_841_rdsk_digest[] = { 38 | 0x74, 0xaa, 0x37, 0x2a, 39 | 0x7f, 0x51, 0xf0, 0xf7, 40 | 0x91, 0xe4, 0x7e, 0x98, 41 | 0x9d, 0xc3, 0xa6, 0x7c, 42 | 0x4c, 0x26, 0xf2, 0xe8 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/idevicererestore/download.c: -------------------------------------------------------------------------------- 1 | /* 2 | * download.c 3 | * file download helper functions 4 | * 5 | * Copyright (c) 2012-2013 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "download.h" 28 | #include "common.h" 29 | 30 | typedef struct { 31 | int length; 32 | char* content; 33 | } curl_response; 34 | 35 | static size_t download_write_buffer_callback(char* data, size_t size, size_t nmemb, curl_response* response) { 36 | size_t total = size * nmemb; 37 | if (total != 0) { 38 | response->content = realloc(response->content, response->length + total + 1); 39 | memcpy(response->content + response->length, data, total); 40 | response->content[response->length + total] = '\0'; 41 | response->length += total; 42 | } 43 | return total; 44 | } 45 | 46 | int download_to_buffer(const char* url, char** buf, uint32_t* length) 47 | { 48 | int res = 0; 49 | CURL* handle = curl_easy_init(); 50 | if (handle == NULL) { 51 | error("ERROR: could not initialize CURL\n"); 52 | return -1; 53 | } 54 | 55 | curl_response response; 56 | response.length = 0; 57 | response.content = malloc(1); 58 | response.content[0] = '\0'; 59 | 60 | if (idevicerestore_debug) 61 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 62 | 63 | /* disable SSL verification to allow download from untrusted https locations */ 64 | curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); 65 | 66 | curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, (curl_write_callback)&download_write_buffer_callback); 67 | curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response); 68 | curl_easy_setopt(handle, CURLOPT_USERAGENT, "InetURL/1.0"); 69 | curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); 70 | curl_easy_setopt(handle, CURLOPT_URL, url); 71 | 72 | curl_easy_perform(handle); 73 | curl_easy_cleanup(handle); 74 | 75 | if (response.length > 0) { 76 | *length = response.length; 77 | *buf = response.content; 78 | } else { 79 | res = -1; 80 | } 81 | 82 | return res; 83 | } 84 | 85 | static int lastprogress = 0; 86 | 87 | static int download_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) 88 | { 89 | double p = (dlnow / dltotal) * 100; 90 | 91 | if (p < 100.0f) { 92 | if ((int)p > lastprogress) { 93 | info("downloading: %d%%\n", (int)p); 94 | lastprogress = (int)p; 95 | } 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | int download_to_file(const char* url, const char* filename, int enable_progress) 102 | { 103 | int res = 0; 104 | CURL* handle = curl_easy_init(); 105 | if (handle == NULL) { 106 | error("ERROR: could not initialize CURL\n"); 107 | return -1; 108 | } 109 | 110 | FILE* f = fopen(filename, "wb"); 111 | if (!f) { 112 | error("ERROR: cannot open '%s' for writing\n", filename); 113 | return -1; 114 | } 115 | 116 | lastprogress = 0; 117 | 118 | if (idevicerestore_debug) 119 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 120 | 121 | /* disable SSL verification to allow download from untrusted https locations */ 122 | curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); 123 | 124 | curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL); 125 | curl_easy_setopt(handle, CURLOPT_WRITEDATA, f); 126 | 127 | if (enable_progress > 0) 128 | curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&download_progress); 129 | 130 | curl_easy_setopt(handle, CURLOPT_NOPROGRESS, enable_progress > 0 ? 0: 1); 131 | curl_easy_setopt(handle, CURLOPT_USERAGENT, "InetURL/1.0"); 132 | curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); 133 | curl_easy_setopt(handle, CURLOPT_URL, url); 134 | 135 | curl_easy_perform(handle); 136 | curl_easy_cleanup(handle); 137 | 138 | off_t sz = ftello(f); 139 | fclose(f); 140 | 141 | if ((sz == 0) || (sz == (off_t)-1)) { 142 | res = -1; 143 | remove(filename); 144 | } 145 | 146 | return res; 147 | } 148 | -------------------------------------------------------------------------------- /src/idevicererestore/download.h: -------------------------------------------------------------------------------- 1 | /* 2 | * download.h 3 | * file download helper functions (header file) 4 | * 5 | * Copyright (c) 2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | #ifndef IDEVICERESTORE_DOWNLOAD_H 23 | #define IDEVICERESTORE_DOWNLOAD_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include 30 | 31 | int download_to_buffer(const char* url, char** buf, uint32_t* length); 32 | int download_to_file(const char* url, const char* filename, int enable_progress); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/idevicererestore/endianness.h: -------------------------------------------------------------------------------- 1 | #ifndef ENDIANNESS_H 2 | #define ENDIANNESS_H 3 | 4 | #ifndef __LITTLE_ENDIAN 5 | #define __LITTLE_ENDIAN 1234 6 | #endif 7 | 8 | #ifndef __BIG_ENDIAN 9 | #define __BIG_ENDIAN 4321 10 | #endif 11 | 12 | #ifndef __BYTE_ORDER 13 | #ifdef __LITTLE_ENDIAN__ 14 | #define __BYTE_ORDER __LITTLE_ENDIAN 15 | #else 16 | #ifdef __BIG_ENDIAN__ 17 | #define __BYTE_ORDER __BIG_ENDIAN 18 | #endif 19 | #endif 20 | #endif 21 | 22 | #ifndef be16toh 23 | #if __BYTE_ORDER == __BIG_ENDIAN 24 | #define be16toh(x) (x) 25 | #else 26 | #define be16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) 27 | #endif 28 | #endif 29 | 30 | #ifndef le16toh 31 | #if __BYTE_ORDER == __BIG_ENDIAN 32 | #define le16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) 33 | #else 34 | #define le16toh(x) (x) 35 | #endif 36 | #endif 37 | 38 | 39 | #ifndef __bswap_32 40 | #define __bswap_32(x) ((((x) & 0xFF000000) >> 24) \ 41 | | (((x) & 0x00FF0000) >> 8) \ 42 | | (((x) & 0x0000FF00) << 8) \ 43 | | (((x) & 0x000000FF) << 24)) 44 | #endif 45 | 46 | #ifndef be32toh 47 | #if __BYTE_ORDER == __BIG_ENDIAN 48 | #define be32toh(x) (x) 49 | #else 50 | #define be32toh(x) __bswap_32(x) 51 | #endif 52 | #endif 53 | 54 | #ifndef htobe32 55 | #define htobe32 be32toh 56 | #endif 57 | 58 | #ifndef le32toh 59 | #if __BYTE_ORDER == __BIG_ENDIAN 60 | #define le32toh(x) __bswap_32(x) 61 | #else 62 | #define le32toh(x) (x) 63 | #endif 64 | #endif 65 | 66 | #ifndef htole32 67 | #define htole32 le32toh 68 | #endif 69 | 70 | #ifndef __bswap_64 71 | #define __bswap_64(x) ((((x) & 0xFF00000000000000ull) >> 56) \ 72 | | (((x) & 0x00FF000000000000ull) >> 40) \ 73 | | (((x) & 0x0000FF0000000000ull) >> 24) \ 74 | | (((x) & 0x000000FF00000000ull) >> 8) \ 75 | | (((x) & 0x00000000FF000000ull) << 8) \ 76 | | (((x) & 0x0000000000FF0000ull) << 24) \ 77 | | (((x) & 0x000000000000FF00ull) << 40) \ 78 | | (((x) & 0x00000000000000FFull) << 56)) 79 | #endif 80 | 81 | #ifndef htobe64 82 | #if __BYTE_ORDER == __BIG_ENDIAN 83 | #define htobe64(x) (x) 84 | #else 85 | #define htobe64(x) __bswap_64(x) 86 | #endif 87 | #endif 88 | 89 | #ifndef be64toh 90 | #define be64toh htobe64 91 | #endif 92 | 93 | #ifndef le64toh 94 | #if __BYTE_ORDER == __LITTLE_ENDIAN 95 | #define le64toh(x) (x) 96 | #else 97 | #define le64toh(x) __bswap_64(x) 98 | #endif 99 | #endif 100 | 101 | #ifndef htole64 102 | #define htole64 le64toh 103 | #endif 104 | 105 | #endif /* ENDIANNESS_H */ 106 | -------------------------------------------------------------------------------- /src/idevicererestore/fdr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fdr.h 3 | * Functions for handling FDR connections 4 | * 5 | * Copyright (c) 2014 BALATON Zoltan. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef IDEVICERESTORE_FDR_H 23 | #define IDEVICERESTORE_FDR_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include 30 | #include "thread.h" /* from libimobiledevice/common */ 31 | 32 | typedef enum { 33 | FDR_CTRL, 34 | FDR_CONN 35 | } fdr_type_t; 36 | 37 | struct fdr_client { 38 | idevice_connection_t connection; 39 | idevice_t device; 40 | fdr_type_t type; 41 | }; 42 | typedef struct fdr_client *fdr_client_t; 43 | 44 | int fdr_connect(idevice_t device, fdr_type_t type, fdr_client_t *fdr); 45 | void fdr_disconnect(fdr_client_t fdr); 46 | void fdr_free(fdr_client_t fdr); 47 | int fdr_poll_and_handle_message(fdr_client_t fdr); 48 | void *fdr_listener_thread(void *cdata); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/idevicererestore/fls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fls.h 3 | * support for .fls file format (found in .bbfw files) 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef FLS_H 22 | #define FLS_H 23 | 24 | #include 25 | 26 | struct _fls_element { 27 | uint32_t type; 28 | uint32_t size; 29 | uint32_t empty; 30 | const unsigned char* data; 31 | } __attribute__((packed)); 32 | typedef struct _fls_element fls_element; 33 | 34 | struct _fls_0c_element { 35 | uint32_t type; 36 | uint32_t size; 37 | uint32_t empty; 38 | uint32_t off_0x0c; 39 | uint32_t off_0x10; 40 | uint32_t off_0x14; 41 | uint32_t off_0x18; 42 | uint32_t data_size; // size without header 43 | uint32_t off_0x20; 44 | uint32_t offset; // absolute offset of data in file 45 | const unsigned char* data; // data+0x14 contains offset to sig blob 46 | } __attribute__((packed)); 47 | typedef struct _fls_0c_element fls_0c_element; 48 | 49 | struct _fls_10_element { 50 | uint32_t type; 51 | uint32_t size; 52 | uint32_t empty; 53 | uint32_t data_size; // size without header 54 | uint32_t off_0x10; 55 | uint32_t offset; 56 | const unsigned char* data; 57 | } __attribute__((packed)); 58 | typedef struct _fls_10_element fls_10_element; 59 | 60 | struct _fls_14_element { 61 | uint32_t type; 62 | uint32_t size; 63 | uint32_t empty; 64 | uint32_t data_size; // size without header 65 | uint32_t off_0x10; 66 | uint32_t offset; 67 | const unsigned char* data; 68 | } __attribute__((packed)); 69 | typedef struct _fls_14_element fls_14_element; 70 | 71 | typedef struct { 72 | unsigned int num_elements; 73 | unsigned int max_elements; 74 | fls_element** elements; 75 | const fls_0c_element* c_element; 76 | void* data; 77 | uint32_t size; 78 | } fls_file; 79 | 80 | fls_file* fls_parse(unsigned char* data, unsigned int size); 81 | void fls_free(fls_file* fls); 82 | int fls_update_sig_blob(fls_file* fls, const unsigned char* data, unsigned int size); 83 | int fls_insert_ticket(fls_file* fls, const unsigned char* data, unsigned int size); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/idevicererestore/globals.h: -------------------------------------------------------------------------------- 1 | // 2 | // globals.h 3 | // idevicererestore 4 | // 5 | // Created by notjon on 12/8/18. 6 | // Copyright © 2018 a. All rights reserved. 7 | // 8 | 9 | #ifndef globals_h 10 | #define globals_h 11 | 12 | #if 0 13 | const char *basebandPath; 14 | const char *manifestPath; 15 | #endif 16 | 17 | #endif /* globals_h */ 18 | -------------------------------------------------------------------------------- /src/idevicererestore/idevicerestore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * idevicerestore.h 3 | * Restore device firmware and filesystem 4 | * 5 | * Copyright (c) 2010-2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012-2015 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_H 25 | #define IDEVICERESTORE_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | // the flag with value 1 is reserved for internal use only. don't use it. 36 | #define FLAG_DEBUG 1 << 1 37 | #define FLAG_ERASE 1 << 2 38 | #define FLAG_CUSTOM 1 << 3 39 | #define FLAG_EXCLUDE 1 << 4 40 | #define FLAG_PWN 1 << 5 41 | #define FLAG_NOACTION 1 << 6 42 | #define FLAG_SHSHONLY 1 << 7 43 | #define FLAG_LATEST 1 << 8 44 | #define FLAG_RERESTORE 1 << 9 45 | #define FLAG_UPDATE 1 << 10 46 | #define FLAG_OTA_BBFW 1 << 11 47 | #define FLAG_UNOFFICIAL_BBFW 1 << 12 48 | #define FLAG_OLD_OTA_BBFW 1 << 13 49 | #define FLAG_OTA_BLOB 1 << 14 50 | 51 | struct idevicerestore_client_t; 52 | 53 | enum { 54 | RESTORE_STEP_DETECT = 0, 55 | RESTORE_STEP_PREPARE, 56 | RESTORE_STEP_UPLOAD_FS, 57 | RESTORE_STEP_VERIFY_FS, 58 | RESTORE_STEP_FLASH_FW, 59 | RESTORE_STEP_FLASH_BB, 60 | RESTORE_NUM_STEPS 61 | }; 62 | 63 | typedef void (*idevicerestore_progress_cb_t)(int step, double step_progress, void* userdata); 64 | 65 | struct idevicerestore_client_t* idevicerestore_client_new(void); 66 | void idevicerestore_client_free(struct idevicerestore_client_t* client); 67 | 68 | void idevicerestore_set_ecid(struct idevicerestore_client_t* client, unsigned long long ecid); 69 | void idevicerestore_set_udid(struct idevicerestore_client_t* client, const char* udid); 70 | void idevicerestore_set_flags(struct idevicerestore_client_t* client, int flags); 71 | void idevicerestore_set_ipsw(struct idevicerestore_client_t* client, const char* path); 72 | void idevicerestore_set_cache_path(struct idevicerestore_client_t* client, const char* path); 73 | void idevicerestore_set_progress_callback(struct idevicerestore_client_t* client, idevicerestore_progress_cb_t cbfunc, void* userdata); 74 | void idevicerestore_set_info_stream(FILE* strm); 75 | void idevicerestore_set_error_stream(FILE* strm); 76 | void idevicerestore_set_debug_stream(FILE* strm); 77 | 78 | int idevicerestore_start(struct idevicerestore_client_t* client); 79 | const char* idevicerestore_get_error(void); 80 | 81 | void usage(int argc, char* argv[]); 82 | int check_mode(struct idevicerestore_client_t* client); 83 | const char* check_hardware_model(struct idevicerestore_client_t* client); 84 | int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); 85 | int is_image4_supported(struct idevicerestore_client_t* client); 86 | int get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 87 | int get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 88 | int get_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss); 89 | void fixup_tss(plist_t tss); 90 | int build_manifest_get_identity_count(plist_t build_manifest); 91 | int build_manifest_check_compatibility(plist_t build_manifest, const char* product); 92 | void build_manifest_get_version_information(plist_t build_manifest, struct idevicerestore_client_t* client); 93 | plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t identity); 94 | plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model); 95 | plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_t build_manifest, const char *hardware_model, const char *behavior); 96 | int build_manifest_get_build_count(plist_t build_manifest); 97 | void build_identity_print_information(plist_t build_identity); 98 | int build_identity_has_component(plist_t build_identity, const char* component); 99 | int build_identity_get_component_path(plist_t build_identity, const char* component, char** path); 100 | int ipsw_extract_filesystem(const char* ipsw, plist_t build_identity, char** filesystem); 101 | int extract_component(const char* ipsw, const char* path, unsigned char** component_data, unsigned int* component_size); 102 | int personalize_component(const char *component, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size); 103 | 104 | const char* get_component_name(const char* filename); 105 | 106 | 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/idevicererestore/img3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * img3.h 3 | * Functions for handling with Apple's IMG3 format 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * Copyright (c) 2010 Martin Szulecki. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_IMG3_H 25 | #define IDEVICERESTORE_IMG3_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef enum { 32 | kNorContainer = 0x696D6733, // img3 33 | kImg3Container = 0x496D6733, // Img3 34 | k8900Container = 0x30303938, // 8900 35 | kImg2Container = 0x494D4732 // IMG2 36 | } img3_container; 37 | 38 | typedef enum { 39 | kDataElement = 0x44415441, // DATA 40 | kTypeElement = 0x54595045, // TYPE 41 | kKbagElement = 0x4B424147, // KBAG 42 | kShshElement = 0x53485348, // SHSH 43 | kCertElement = 0x43455254, // CERT 44 | kChipElement = 0x43484950, // CHIP 45 | kProdElement = 0x50524F44, // PROD 46 | kSdomElement = 0x53444F4D, // SDOM 47 | kVersElement = 0x56455253, // VERS 48 | kBordElement = 0x424F5244, // BORD 49 | kSepoElement = 0x5345504F, // SEPO 50 | kEcidElement = 0x45434944, // ECID 51 | kUnknElement = 0x53414c54 // FIXME 52 | } img3_element_type; 53 | 54 | typedef struct { 55 | unsigned int signature; 56 | unsigned int full_size; 57 | unsigned int data_size; 58 | unsigned int shsh_offset; 59 | unsigned int image_type; 60 | } img3_header; 61 | 62 | typedef struct { 63 | unsigned int signature; 64 | unsigned int full_size; 65 | unsigned int data_size; 66 | } img3_element_header; 67 | 68 | typedef struct { 69 | img3_element_header* header; 70 | img3_element_type type; 71 | unsigned char* data; 72 | } img3_element; 73 | 74 | typedef struct { 75 | unsigned char* data; 76 | img3_header* header; 77 | int num_elements; 78 | img3_element* elements[16]; 79 | int idx_ecid_element; 80 | int idx_shsh_element; 81 | int idx_cert_element; 82 | /* img3_element* type_element; 83 | img3_element* data_element; 84 | img3_element* vers_element; 85 | img3_element* sepo_element; 86 | img3_element* bord_element; 87 | img3_element* sepo2_element; 88 | img3_element* chip_element; 89 | img3_element* bord2_element; 90 | img3_element* kbag1_element; 91 | img3_element* kbag2_element; 92 | img3_element* ecid_element; 93 | img3_element* shsh_element; 94 | img3_element* cert_element; 95 | img3_element* unkn_element;*/ 96 | } img3_file; 97 | 98 | int img3_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, const unsigned char* blob, unsigned int blob_size, unsigned char** img3_data, unsigned int *img3_size); 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/idevicererestore/img4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * img4.c 3 | * Functions for handling the new IMG4 format 4 | * 5 | * Copyright (c) 2013 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "common.h" 26 | #include "img4.h" 27 | 28 | #define ASN1_CONSTRUCTED 0x20 29 | #define ASN1_SEQUENCE 0x10 30 | #define ASN1_CONTEXT_SPECIFIC 0x80 31 | #define ASN1_IA5_STRING 0x16 32 | 33 | #define IMG4_MAGIC "IMG4" 34 | #define IMG4_MAGIC_SIZE 4 35 | 36 | static unsigned char* asn1_create_element_header(unsigned char type, unsigned int size, unsigned char** data, unsigned int *data_size) 37 | { 38 | unsigned char buf[6]; 39 | unsigned int off = 0; 40 | 41 | if (!type || size == 0 || !data || !data_size) { 42 | return NULL; 43 | } 44 | 45 | buf[off++] = type; 46 | 47 | // first, calculate the size 48 | if (size >= 0x1000000) { 49 | // 1+4 bytes length 50 | buf[off++] = 0x84; 51 | buf[off++] = (size >> 24) & 0xFF; 52 | buf[off++] = (size >> 16) & 0xFF; 53 | buf[off++] = (size >> 8) & 0xFF; 54 | buf[off++] = size & 0xFF; 55 | } else if (size >= 0x10000) { 56 | // 1+3 bytes length 57 | buf[off++] = 0x83; 58 | buf[off++] = (size >> 16) & 0xFF; 59 | buf[off++] = (size >> 8) & 0xFF; 60 | buf[off++] = size & 0xFF; 61 | } else if (size >= 0x100) { 62 | // 1+2 bytes length 63 | buf[off++] = 0x82; 64 | buf[off++] = (size >> 8) & 0xFF; 65 | buf[off++] = (size & 0xFF); 66 | } else if (size >= 0x80) { 67 | // 1+1 byte length 68 | buf[off++] = 0x81; 69 | buf[off++] = (size & 0xFF); 70 | } else { 71 | // 1 byte length 72 | buf[off++] = size & 0xFF; 73 | } 74 | 75 | *data = malloc(off); 76 | memcpy(*data, buf, off); 77 | *data_size = off; 78 | 79 | return *data; 80 | } 81 | 82 | int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, const unsigned char* blob, unsigned int blob_size, unsigned char** img4_data, unsigned int *img4_size) 83 | { 84 | unsigned char* magic_header = NULL; 85 | unsigned int magic_header_size = 0; 86 | unsigned char* blob_header = NULL; 87 | unsigned int blob_header_size = 0; 88 | unsigned char* img4header = NULL; 89 | unsigned int img4header_size = 0; 90 | unsigned int content_size; 91 | unsigned char* outbuf; 92 | unsigned char* p; 93 | 94 | if (!component_name || !component_data || component_size == 0 || !blob || blob_size == 0 || !img4_data || !img4_size) { 95 | return -1; 96 | } 97 | 98 | info("Personalizing IMG4 component %s...\n", component_name); 99 | 100 | /* first we need check if we have to change the tag for the given component */ 101 | // FIXME: write proper ASN1 handling code for this 102 | if (strcmp(component_name, "RestoreKernelCache") == 0) { 103 | memcpy((char*)component_data+0xD, "rkrn", 4); 104 | } else if (strcmp(component_name, "RestoreDeviceTree") == 0) { 105 | memcpy((char*)component_data+0xD, "rdtr", 4); 106 | } else if (strcmp(component_name, "RestoreSEP") == 0) { 107 | memcpy((char*)component_data+0xD, "rsep", 4); 108 | } 109 | 110 | // create element header for the "IMG4" magic 111 | asn1_create_element_header(ASN1_IA5_STRING, IMG4_MAGIC_SIZE, &magic_header, &magic_header_size); 112 | // create element header for the blob (ApImg4Ticket) 113 | asn1_create_element_header(ASN1_CONTEXT_SPECIFIC|ASN1_CONSTRUCTED, blob_size, &blob_header, &blob_header_size); 114 | 115 | // calculate the size for the final IMG4 file (asn1 sequence) 116 | content_size = magic_header_size + IMG4_MAGIC_SIZE + component_size + blob_header_size + blob_size; 117 | 118 | // create element header for the final IMG4 asn1 blob 119 | asn1_create_element_header(ASN1_SEQUENCE|ASN1_CONSTRUCTED, content_size, &img4header, &img4header_size); 120 | 121 | outbuf = (unsigned char*)malloc(img4header_size + content_size); 122 | if (!outbuf) { 123 | if (magic_header) { 124 | free(magic_header); 125 | } 126 | if (blob_header) { 127 | free(blob_header); 128 | } 129 | if (img4header) { 130 | free(img4header); 131 | } 132 | error("ERROR: out of memory when personalizing IMG4 component %s\n", component_name); 133 | return -1; 134 | } 135 | p = outbuf; 136 | 137 | // now put everything together 138 | memcpy(p, img4header, img4header_size); 139 | p += img4header_size; 140 | memcpy(p, magic_header, magic_header_size); 141 | p += magic_header_size; 142 | memcpy(p, IMG4_MAGIC, IMG4_MAGIC_SIZE); 143 | p += IMG4_MAGIC_SIZE; 144 | memcpy(p, component_data, component_size); 145 | p += component_size; 146 | memcpy(p, blob_header, blob_header_size); 147 | p += blob_header_size; 148 | memcpy(p, blob, blob_size); 149 | p += blob_size; 150 | 151 | *img4_data = outbuf; 152 | *img4_size = (p - outbuf); 153 | 154 | if (magic_header) { 155 | free(magic_header); 156 | } 157 | if (blob_header) { 158 | free(blob_header); 159 | } 160 | if (img4header) { 161 | free(img4header); 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /src/idevicererestore/img4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * img4.h 3 | * Functions for handling the new IMG4 format 4 | * 5 | * Copyright (c) 2013 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef IDEVICERESTORE_IMG4_H 23 | #define IDEVICERESTORE_IMG4_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, const unsigned char* blob, unsigned int blob_size, unsigned char** img4_data, unsigned int *img4_size); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/idevicererestore/ipsw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ipsw.h 3 | * Definitions for IPSW utilities 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * Copyright (c) 2010 Martin Szulecki. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_IPSW_H 25 | #define IDEVICERESTORE_IPSW_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | typedef struct { 36 | int index; 37 | char* name; 38 | unsigned int size; 39 | unsigned char* data; 40 | } ipsw_file; 41 | 42 | int ipsw_get_file_size(const char* ipsw, const char* infile, off_t* size); 43 | int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfile); 44 | int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, const char* outfile, int print_progress); 45 | int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** pbuffer, unsigned int* psize); 46 | int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *tss_enabled); 47 | int ipsw_extract_restore_plist(const char* ipsw, plist_t* restore_plist); 48 | void ipsw_free_file(ipsw_file* file); 49 | 50 | int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl, unsigned char* sha1buf); 51 | int ipsw_download_latest_fw(plist_t version_data, const char* product, const char* todir, char** ipswfile); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/idevicererestore/locking.c: -------------------------------------------------------------------------------- 1 | /* 2 | * locking.c 3 | * locking extras 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifdef WIN32 22 | #include 23 | #else 24 | #include 25 | #endif 26 | 27 | #include "locking.h" 28 | #include "common.h" 29 | 30 | int lock_file(const char* filename, lock_info_t* lockinfo) 31 | { 32 | if (!lockinfo) { 33 | return -1; 34 | } 35 | #ifdef WIN32 36 | lockinfo->fp = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 37 | if (lockinfo->fp == INVALID_HANDLE_VALUE) { 38 | debug("ERROR: could not open or create lockfile '%s'\n", filename); 39 | return -1; 40 | } 41 | 42 | lockinfo->ldata.Offset = 0; 43 | lockinfo->ldata.OffsetHigh = 0; 44 | 45 | if (!LockFileEx(lockinfo->fp, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &lockinfo->ldata)) { 46 | debug("ERROR: can't lock file, error %d\n", GetLastError()); 47 | CloseHandle(lockinfo->fp); 48 | lockinfo->fp = INVALID_HANDLE_VALUE; 49 | return -1; 50 | } 51 | #else 52 | lockinfo->fp = fopen(filename, "a+"); 53 | 54 | if (!lockinfo->fp) { 55 | debug("ERROR: could not open or create lockfile '%s'\n", filename); 56 | return -1; 57 | } 58 | 59 | lockinfo->ldata.l_type = F_WRLCK; 60 | lockinfo->ldata.l_whence = SEEK_SET; 61 | lockinfo->ldata.l_start = 0; 62 | lockinfo->ldata.l_len = 0; 63 | 64 | if (fcntl(fileno(lockinfo->fp), F_SETLKW, &lockinfo->ldata) < 0) { 65 | debug("ERROR: can't lock file, error %d\n", errno); 66 | fclose(lockinfo->fp); 67 | lockinfo->fp = NULL; 68 | return -1; 69 | } 70 | #endif 71 | return 0; 72 | } 73 | 74 | int unlock_file(lock_info_t* lockinfo) 75 | { 76 | if (!lockinfo) { 77 | return -1; 78 | } 79 | #ifdef WIN32 80 | if (lockinfo->fp == INVALID_HANDLE_VALUE) { 81 | return -1; 82 | } 83 | 84 | lockinfo->ldata.Offset = 0; 85 | lockinfo->ldata.OffsetHigh = 0; 86 | 87 | if (!UnlockFileEx(lockinfo->fp, 0, 1, 0, &lockinfo->ldata)) { 88 | debug("ERROR: can't unlock file, error %d\n", GetLastError()); 89 | CloseHandle(lockinfo->fp); 90 | lockinfo->fp = INVALID_HANDLE_VALUE; 91 | return -1; 92 | } 93 | CloseHandle(lockinfo->fp); 94 | lockinfo->fp = INVALID_HANDLE_VALUE; 95 | #else 96 | if (!lockinfo->fp) { 97 | return -1; 98 | } 99 | 100 | lockinfo->ldata.l_type = F_UNLCK; 101 | lockinfo->ldata.l_whence = SEEK_SET; 102 | lockinfo->ldata.l_start = 0; 103 | lockinfo->ldata.l_len = 0; 104 | 105 | if (fcntl(fileno(lockinfo->fp), F_SETLK, &lockinfo->ldata) < 0) { 106 | debug("ERROR: can't unlock file, error %d\n", errno); 107 | fclose(lockinfo->fp); 108 | lockinfo->fp = NULL; 109 | return -1; 110 | } 111 | fclose(lockinfo->fp); 112 | lockinfo->fp = NULL; 113 | #endif 114 | return 0; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /src/idevicererestore/locking.h: -------------------------------------------------------------------------------- 1 | /* 2 | * locking.h 3 | * locking extras header file 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef LOCKING_H 22 | #define LOCKING_H 23 | #include 24 | #ifdef WIN32 25 | #include 26 | #else 27 | #include 28 | #endif 29 | 30 | typedef struct { 31 | #ifdef WIN32 32 | HANDLE fp; 33 | OVERLAPPED ldata; 34 | #else 35 | FILE* fp; 36 | struct flock ldata; 37 | #endif 38 | } lock_info_t; 39 | 40 | int lock_file(const char* filename, lock_info_t* lockp); 41 | int unlock_file(lock_info_t* lockp); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/idevicererestore/mbn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mbn.c 3 | * support for .mbn file format (found in .bbfw files) 4 | * 5 | * Copyright (c) 2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include "mbn.h" 26 | #include "common.h" 27 | 28 | mbn_file* mbn_parse(unsigned char* data, unsigned int size) 29 | { 30 | mbn_file* mbn = (mbn_file*)malloc(sizeof(mbn_file)); 31 | if (!mbn) { 32 | return NULL; 33 | } 34 | memset(mbn, '\0', sizeof(mbn_file)); 35 | mbn->data = malloc(size); 36 | mbn->size = size; 37 | memcpy(mbn->data, data, size); 38 | /* FIXME: header parsing is not big endian safe */ 39 | if (memcmp(data, MBN_V2_MAGIC, MBN_V2_MAGIC_SIZE) == 0) { 40 | mbn->version = 2; 41 | memcpy(&mbn->header.v2, data, sizeof(mbn_header_v2)); 42 | mbn->parsed_size = mbn->header.v2.data_size + sizeof(mbn_header_v2); 43 | } else if (memcmp(data, MBN_V1_MAGIC, MBN_V1_MAGIC_SIZE) == 0) { 44 | mbn->version = 1; 45 | memcpy(&mbn->header.v1, data, sizeof(mbn_header_v1)); 46 | mbn->parsed_size = mbn->header.v1.data_size + sizeof(mbn_header_v1); 47 | } else if (memcmp(data, BIN_MAGIC, BIN_MAGIC_SIZE) == 0) { 48 | mbn->version = 3; 49 | memcpy(&mbn->header.bin, data, sizeof(bin_header)); 50 | mbn->parsed_size = mbn->header.bin.total_size; 51 | } else if (memcmp(data, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) { 52 | mbn->version = 4; 53 | memcpy(&mbn->header.elf, data, sizeof(elf_header)); 54 | // we cheat here since we don't parse the actual ELF file 55 | mbn->parsed_size = mbn->size; 56 | } else { 57 | debug("DEBUG: Unknown file format passed to %s\n", __func__); 58 | } 59 | if (mbn->parsed_size != mbn->size) { 60 | info("WARNING: size mismatch when parsing MBN file. Continuing anyway.\n"); 61 | } 62 | return mbn; 63 | } 64 | 65 | void mbn_free(mbn_file* mbn) 66 | { 67 | if (mbn) { 68 | if (mbn->data) { 69 | free(mbn->data); 70 | } 71 | free(mbn); 72 | } 73 | } 74 | 75 | int mbn_update_sig_blob(mbn_file* mbn, const unsigned char* sigdata, unsigned int siglen) 76 | { 77 | if (!mbn) { 78 | error("ERROR: %s: no data\n", __func__); 79 | return -1; 80 | } 81 | mbn->parsed_sig_offset = mbn->size - siglen; 82 | if ((mbn->parsed_sig_offset + siglen) > mbn->size) { 83 | error("ERROR: %s: signature is larger than mbn file size\n", __func__); 84 | return -1; 85 | } 86 | 87 | memcpy(mbn->data + mbn->parsed_sig_offset, sigdata, siglen); 88 | 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/idevicererestore/mbn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mbn.h 3 | * support for .mbn file format (found in .bbfw files) 4 | * 5 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef MBN_H 22 | #define MBN_H 23 | 24 | #include 25 | 26 | #define MBN_V1_MAGIC "\x0A\x00\x00\x00" 27 | #define MBN_V1_MAGIC_SIZE 4 28 | 29 | struct _mbn_header_v1 { 30 | uint32_t type; // the signed .mbn files have 0xA as value. 31 | uint32_t unk_0x04; 32 | uint32_t unk_0x08; 33 | uint32_t unk_0x0c; 34 | uint32_t data_size; // data_size = total_size - sizeof(mbn_header) 35 | uint32_t sig_offset; // real offset = enc_sig_offset & 0xFFFFFF00 36 | uint32_t unk_0x18; 37 | uint32_t unk_0x1c; 38 | uint32_t unk_0x20; 39 | uint32_t unk_0x24; 40 | } __attribute__((packed)); 41 | typedef struct _mbn_header_v1 mbn_header_v1; 42 | 43 | #define MBN_V2_MAGIC "\xD1\xDC\x4B\x84\x34\x10\xD7\x73" 44 | #define MBN_V2_MAGIC_SIZE 8 45 | 46 | struct _mbn_header_v2 { 47 | unsigned char magic1[8]; 48 | uint32_t unk_0x08; 49 | uint32_t unk_0x0c; // 0xFFFFFFFF 50 | uint32_t unk_0x10; // 0xFFFFFFFF 51 | uint32_t header_size; 52 | uint32_t unk_0x18; 53 | uint32_t data_size; // data_size = total_size - sizeof(mbn_header_v2) 54 | uint32_t sig_offset; 55 | uint32_t unk_0x24; 56 | uint32_t unk_0x28; 57 | uint32_t unk_0x2c; 58 | uint32_t unk_0x30; 59 | uint32_t unk_0x34; // 0x1 60 | uint32_t unk_0x38; // 0x1 61 | uint32_t unk_0x3c; // 0xFFFFFFFF 62 | uint32_t unk_0x40; // 0xFFFFFFFF 63 | uint32_t unk_0x44; // 0xFFFFFFFF 64 | uint32_t unk_0x48; // 0xFFFFFFFF 65 | uint32_t unk_0x4c; // 0xFFFFFFFF 66 | } __attribute__((packed)); 67 | typedef struct _mbn_header_v2 mbn_header_v2; 68 | 69 | #define BIN_MAGIC "\x7D\x04\x00\xEA\x6C\x69\x48\x55" 70 | #define BIN_MAGIC_SIZE 8 71 | 72 | struct _bin_header { 73 | unsigned char magic[8]; 74 | uint32_t unk_0x08; 75 | uint32_t version; 76 | uint32_t total_size; // size including header 77 | uint32_t unk_0x14; // some offset 78 | } __attribute__((packed)); 79 | typedef struct _bin_header bin_header; 80 | 81 | #define ELF_MAGIC "\x7F\x45\x4C\x46\x01\x01\x01\x00" // ELF magic, 32bit, little endian, SYSV 82 | #define ELF_MAGIC_SIZE 8 83 | 84 | struct _elf_header { 85 | unsigned char magic[8]; 86 | } __attribute__((packed)); 87 | typedef struct _elf_header elf_header; 88 | 89 | typedef struct { 90 | uint32_t version; 91 | union { 92 | mbn_header_v1 v1; 93 | mbn_header_v2 v2; 94 | bin_header bin; 95 | elf_header elf; 96 | } header; 97 | uint32_t parsed_size; 98 | uint32_t parsed_sig_offset; 99 | void* data; 100 | uint32_t size; 101 | } mbn_file; 102 | 103 | mbn_file* mbn_parse(unsigned char* data, unsigned int size); 104 | void mbn_free(mbn_file* mbn); 105 | int mbn_update_sig_blob(mbn_file* mbn, const unsigned char* data, unsigned int size); 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/idevicererestore/normal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * normal.h 3 | * Functions for handling idevices in normal mode 4 | * 5 | * Copyright (c) 2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012-2015 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_NORMAL_H 25 | #define IDEVICERESTORE_NORMAL_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | struct normal_client_t { 36 | idevice_t device; 37 | lockdownd_client_t client; 38 | const char* ipsw; 39 | plist_t tss; 40 | }; 41 | 42 | 43 | int normal_check_mode(struct idevicerestore_client_t* client); 44 | const char* normal_check_hardware_model(struct idevicerestore_client_t* client); 45 | int normal_client_new(struct idevicerestore_client_t* client); 46 | void normal_client_free(struct idevicerestore_client_t* client); 47 | int normal_open_with_timeout(struct idevicerestore_client_t* client); 48 | int normal_enter_recovery(struct idevicerestore_client_t* client); 49 | int normal_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); 50 | int normal_is_image4_supported(struct idevicerestore_client_t* client); 51 | int normal_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 52 | int normal_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 53 | int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/idevicererestore/partial.h: -------------------------------------------------------------------------------- 1 | /** 2 | * libpartialzip-1.0 - libpartialzip.h 3 | * Copyright (C) 2010 David Wang 4 | * 5 | * Modified by: 6 | * Copyright (C) 2010-2013 Joshua Hill 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | **/ 21 | 22 | #ifndef LIBPARTIAL_H 23 | #define LIBPARTIAL_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef _WIN32 34 | #ifndef _MSC_VER 35 | #define _MSC_VER 36 | #endif 37 | #define fseeko fseeko64 38 | #define ftello ftello64 39 | #define off_t off64_t 40 | #define mkdir(x, y) mkdir(x) 41 | #define PATH_SEPARATOR "\\" 42 | #define sleep(n) Sleep(1000 * n) 43 | #else 44 | #define PATH_SEPARATOR "/" 45 | #endif 46 | 47 | #ifdef _MSC_VER 48 | #define STATIC_INLINE static __inline 49 | #else 50 | #define STATIC_INLINE static inline 51 | #endif 52 | 53 | #define TRUE 1 54 | #define FALSE 0 55 | 56 | #define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x)) 57 | #define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x)) 58 | 59 | #define IS_BIG_ENDIAN 0 60 | #define IS_LITTLE_ENDIAN 1 61 | 62 | #define TIME_OFFSET_FROM_UNIX 2082844800L 63 | #define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX) 64 | #define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX) 65 | 66 | #define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); perror("error"); fflush(stderr); exit(1); } 67 | 68 | extern char endianness; 69 | 70 | STATIC_INLINE void flipEndian(unsigned char* x, int length) { 71 | int i; 72 | unsigned char tmp; 73 | 74 | if(endianness == IS_BIG_ENDIAN) { 75 | return; 76 | } else { 77 | for(i = 0; i < (length / 2); i++) { 78 | tmp = x[i]; 79 | x[i] = x[length - i - 1]; 80 | x[length - i - 1] = tmp; 81 | } 82 | } 83 | } 84 | 85 | STATIC_INLINE void flipEndianLE(unsigned char* x, int length) { 86 | int i; 87 | unsigned char tmp; 88 | 89 | if(endianness == IS_LITTLE_ENDIAN) { 90 | return; 91 | } else { 92 | for(i = 0; i < (length / 2); i++) { 93 | tmp = x[i]; 94 | x[i] = x[length - i - 1]; 95 | x[length - i - 1] = tmp; 96 | } 97 | } 98 | } 99 | 100 | STATIC_INLINE void hexToBytes(const char* hex, uint8_t** buffer, size_t* bytes) { 101 | size_t i; 102 | *bytes = strlen(hex) / 2; 103 | *buffer = (uint8_t*) malloc(*bytes); 104 | for(i = 0; i < *bytes; i++) { 105 | uint32_t byte; 106 | sscanf(hex, "%2x", &byte); 107 | (*buffer)[i] = byte; 108 | hex += 2; 109 | } 110 | } 111 | 112 | STATIC_INLINE void hexToInts(const char* hex, unsigned int** buffer, size_t* bytes) { 113 | size_t i; 114 | *bytes = strlen(hex) / 2; 115 | *buffer = (unsigned int*) malloc((*bytes) * sizeof(int)); 116 | for(i = 0; i < *bytes; i++) { 117 | sscanf(hex, "%2x", &((*buffer)[i])); 118 | hex += 2; 119 | } 120 | } 121 | 122 | struct io_func_struct; 123 | 124 | typedef int (*partial_zip_read)(struct io_func_struct* io, off_t location, size_t size, void *buffer); 125 | typedef int (*partial_zip_write)(struct io_func_struct* io, off_t location, size_t size, void *buffer); 126 | typedef void (*partial_zip_close)(struct io_func_struct* io); 127 | 128 | typedef struct { 129 | void* data; 130 | partial_zip_read read; 131 | partial_zip_write write; 132 | partial_zip_close close; 133 | } partialzip_io_funcs; 134 | 135 | #ifdef _MSC_VER 136 | #define ATTRIBUTE_PACKED 137 | #pragma pack(push) 138 | #pragma pack(1) 139 | #else 140 | #define ATTRIBUTE_PACKED __attribute__ ((packed)) 141 | #endif 142 | 143 | typedef struct { 144 | uint32_t signature; 145 | uint16_t diskNo; 146 | uint16_t CDDiskNo; 147 | uint16_t CDDiskEntries; 148 | uint16_t CDEntries; 149 | uint32_t CDSize; 150 | uint32_t CDOffset; 151 | uint16_t lenComment; 152 | } ATTRIBUTE_PACKED partialzip_end_of_cd_t; 153 | 154 | typedef struct { 155 | uint32_t signature; 156 | uint16_t version; 157 | uint16_t versionExtract; 158 | uint16_t flags; 159 | uint16_t method; 160 | uint16_t modTime; 161 | uint16_t modDate; 162 | uint32_t crc32; 163 | uint32_t compressedSize; 164 | uint32_t size; 165 | uint16_t lenFileName; 166 | uint16_t lenExtra; 167 | uint16_t lenComment; 168 | uint16_t diskStart; 169 | uint16_t internalAttr; 170 | uint32_t externalAttr; 171 | uint32_t offset; 172 | } ATTRIBUTE_PACKED partialzip_file_t; 173 | 174 | typedef struct { 175 | uint32_t signature; 176 | uint16_t versionExtract; 177 | uint16_t flags; 178 | uint16_t method; 179 | uint16_t modTime; 180 | uint16_t modDate; 181 | uint32_t crc32; 182 | uint32_t compressedSize; 183 | uint32_t size; 184 | uint16_t lenFileName; 185 | uint16_t lenExtra; 186 | } ATTRIBUTE_PACKED partialzip_local_file_t; 187 | 188 | #ifdef _MSC_VER 189 | #pragma pack(pop) 190 | #endif 191 | 192 | typedef struct partialzip_info partialzip_t; 193 | 194 | typedef void (*partialzip_progress_callback_t)(partialzip_t* info, partialzip_file_t* file, size_t progress); 195 | 196 | struct partialzip_info { 197 | char* url; 198 | uint64_t length; 199 | CURL* hIPSW; 200 | char* centralDirectory; 201 | size_t centralDirectoryRecvd; 202 | partialzip_end_of_cd_t* centralDirectoryDesc; 203 | char centralDirectoryEnd[0xffff + sizeof(partialzip_end_of_cd_t)]; 204 | size_t centralDirectoryEndRecvd; 205 | partialzip_progress_callback_t progressCallback; 206 | }; 207 | 208 | 209 | partialzip_t* partialzip_open(const char* url); 210 | partialzip_file_t* partialzip_find_file(partialzip_t* info, const char* fileName); 211 | partialzip_file_t* partialzip_list_files(partialzip_t* info); 212 | unsigned char* partialzip_get_file(partialzip_t* info, partialzip_file_t* file); 213 | void partialzip_close(partialzip_t* info); 214 | int partialzip_download_file(const char* url, const char* path, const char* output); 215 | void partialzip_set_progress_callback(partialzip_t* info, partialzip_progress_callback_t progressCallback); 216 | void partialzip_free_file(partialzip_file_t* file); 217 | 218 | #ifdef __cplusplus 219 | } 220 | #endif 221 | 222 | #endif 223 | -------------------------------------------------------------------------------- /src/idevicererestore/recovery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * recovery.h 3 | * Functions for handling idevices in recovery mode 4 | * 5 | * Copyright (c) 2010-2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_RECOVERY_H 25 | #define IDEVICERESTORE_RECOVERY_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "common.h" 36 | 37 | struct recovery_client_t { 38 | irecv_client_t client; 39 | const char* ipsw; 40 | plist_t tss; 41 | }; 42 | 43 | int recovery_check_mode(struct idevicerestore_client_t* client); 44 | int recovery_client_new(struct idevicerestore_client_t* client); 45 | void recovery_client_free(struct idevicerestore_client_t* client); 46 | int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity); 47 | int recovery_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component); 48 | int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_identity); 49 | int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t build_identity); 50 | int recovery_send_devicetree(struct idevicerestore_client_t* client, plist_t build_identity); 51 | int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_identity); 52 | int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t build_identity); 53 | int recovery_send_reset(struct idevicerestore_client_t* client); 54 | int recovery_send_ticket(struct idevicerestore_client_t* client); 55 | int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable); 56 | int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); 57 | int recovery_is_image4_supported(struct idevicerestore_client_t* client); 58 | int recovery_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 59 | int recovery_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); 60 | 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/idevicererestore/restore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * restore.h 3 | * Functions for handling idevices in restore mode 4 | * 5 | * Copyright (c) 2010-2012 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012-2015 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_RESTORE_H 25 | #define IDEVICERESTORE_RESTORE_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | struct restore_client_t { 36 | char* bbfwtmp; 37 | plist_t tss; 38 | plist_t bbtss; 39 | idevice_t device; 40 | char* udid; 41 | unsigned int operation; 42 | const char* filesystem; 43 | uint64_t protocol_version; 44 | restored_client_t client; 45 | }; 46 | 47 | int restore_check_mode(struct idevicerestore_client_t* client); 48 | const char* restore_check_hardware_model(struct idevicerestore_client_t* client); 49 | int restore_client_new(struct idevicerestore_client_t* client); 50 | void restore_client_free(struct idevicerestore_client_t* client); 51 | int restore_reboot(struct idevicerestore_client_t* client); 52 | const char* restore_progress_string(unsigned int operation); 53 | int restore_handle_status_msg(restored_client_t client, plist_t msg); 54 | int restore_handle_progress_msg(struct idevicerestore_client_t* client, plist_t msg); 55 | int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity, const char* filesystem); 56 | int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity); 57 | int restore_send_root_ticket(restored_client_t restore, struct idevicerestore_client_t* client); 58 | int restore_send_kernelcache(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity); 59 | int restore_device(struct idevicerestore_client_t* client, plist_t build_identity, const char* filesystem); 60 | int restore_open_with_timeout(struct idevicerestore_client_t* client); 61 | int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t device, const char* filesystem); 62 | int restore_send_fdr_trust_data(restored_client_t restore, idevice_t device); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/idevicererestore/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * socket.h 3 | * 4 | * Copyright (c) 2012 Martin Szulecki All Rights Reserved. 5 | * Copyright (c) 2012 Nikias Bassen All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef __SOCKET_SOCKET_H 23 | #define __SOCKET_SOCKET_H 24 | 25 | #include 26 | #include 27 | 28 | enum fd_mode { 29 | FDM_READ, 30 | FDM_WRITE, 31 | FDM_EXCEPT 32 | }; 33 | typedef enum fd_mode fd_mode; 34 | 35 | #ifdef WIN32 36 | #include 37 | #define SHUT_RD SD_READ 38 | #define SHUT_WR SD_WRITE 39 | #define SHUT_RDWR SD_BOTH 40 | #else 41 | #include 42 | #endif 43 | 44 | #ifndef WIN32 45 | int socket_create_unix(const char *filename); 46 | int socket_connect_unix(const char *filename); 47 | #endif 48 | int socket_create(uint16_t port); 49 | int socket_connect(const char *addr, uint16_t port); 50 | int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout); 51 | int socket_accept(int fd, uint16_t port); 52 | 53 | int socket_shutdown(int fd, int how); 54 | int socket_close(int fd); 55 | 56 | int socket_receive(int fd, void *data, size_t size); 57 | int socket_peek(int fd, void *data, size_t size); 58 | int socket_receive_timeout(int fd, void *data, size_t size, int flags, 59 | unsigned int timeout); 60 | 61 | int socket_send(int fd, void *data, size_t size); 62 | 63 | void socket_set_verbose(int level); 64 | 65 | #endif /* __SOCKET_SOCKET_H */ 66 | -------------------------------------------------------------------------------- /src/idevicererestore/thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * thread.c 3 | * 4 | * Copyright (c) 2012 Martin Szulecki All Rights Reserved. 5 | * Copyright (c) 2012 Nikias Bassen All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "thread.h" 23 | 24 | int thread_new(thread_t *thread, thread_func_t thread_func, void* data) 25 | { 26 | #ifdef WIN32 27 | HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); 28 | if (th == NULL) { 29 | return -1; 30 | } 31 | *thread = th; 32 | return 0; 33 | #else 34 | int res = pthread_create(thread, NULL, thread_func, data); 35 | return res; 36 | #endif 37 | } 38 | 39 | void thread_free(thread_t thread) 40 | { 41 | #ifdef WIN32 42 | CloseHandle(thread); 43 | #endif 44 | } 45 | 46 | void thread_join(thread_t thread) 47 | { 48 | /* wait for thread to complete */ 49 | #ifdef WIN32 50 | WaitForSingleObject(thread, INFINITE); 51 | #else 52 | pthread_join(thread, NULL); 53 | #endif 54 | } 55 | 56 | void mutex_init(mutex_t* mutex) 57 | { 58 | #ifdef WIN32 59 | InitializeCriticalSection(mutex); 60 | #else 61 | pthread_mutex_init(mutex, NULL); 62 | #endif 63 | } 64 | 65 | void mutex_destroy(mutex_t* mutex) 66 | { 67 | #ifdef WIN32 68 | DeleteCriticalSection(mutex); 69 | #else 70 | pthread_mutex_destroy(mutex); 71 | #endif 72 | } 73 | 74 | void mutex_lock(mutex_t* mutex) 75 | { 76 | #ifdef WIN32 77 | EnterCriticalSection(mutex); 78 | #else 79 | pthread_mutex_lock(mutex); 80 | #endif 81 | } 82 | 83 | void mutex_unlock(mutex_t* mutex) 84 | { 85 | #ifdef WIN32 86 | LeaveCriticalSection(mutex); 87 | #else 88 | pthread_mutex_unlock(mutex); 89 | #endif 90 | } 91 | 92 | void thread_once(thread_once_t *once_control, void (*init_routine)(void)) 93 | { 94 | #ifdef WIN32 95 | while (InterlockedExchange(&(once_control->lock), 1) != 0) { 96 | Sleep(1); 97 | } 98 | if (!once_control->state) { 99 | once_control->state = 1; 100 | init_routine(); 101 | } 102 | InterlockedExchange(&(once_control->lock), 0); 103 | #else 104 | pthread_once(once_control, init_routine); 105 | #endif 106 | } 107 | -------------------------------------------------------------------------------- /src/idevicererestore/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * thread.h 3 | * 4 | * Copyright (c) 2012 Martin Szulecki All Rights Reserved. 5 | * Copyright (c) 2012 Nikias Bassen All Rights Reserved. 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef __THREAD_H 23 | #define __THREAD_H 24 | 25 | #ifdef WIN32 26 | #include 27 | typedef HANDLE thread_t; 28 | typedef CRITICAL_SECTION mutex_t; 29 | typedef volatile struct { 30 | LONG lock; 31 | int state; 32 | } thread_once_t; 33 | #define THREAD_ONCE_INIT {0, 0} 34 | #define THREAD_ID GetCurrentThreadId() 35 | #else 36 | #include 37 | typedef pthread_t thread_t; 38 | typedef pthread_mutex_t mutex_t; 39 | typedef pthread_once_t thread_once_t; 40 | #define THREAD_ONCE_INIT PTHREAD_ONCE_INIT 41 | #define THREAD_ID pthread_self() 42 | #endif 43 | 44 | typedef void* (*thread_func_t)(void* data); 45 | 46 | int thread_new(thread_t* thread, thread_func_t thread_func, void* data); 47 | void thread_free(thread_t thread); 48 | void thread_join(thread_t thread); 49 | 50 | void mutex_init(mutex_t* mutex); 51 | void mutex_destroy(mutex_t* mutex); 52 | void mutex_lock(mutex_t* mutex); 53 | void mutex_unlock(mutex_t* mutex); 54 | 55 | void thread_once(thread_once_t *once_control, void (*init_routine)(void)); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/idevicererestore/tss.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tss.h 3 | * Definitions for communicating with Apple's TSS server. 4 | * 5 | * Copyright (c) 2013 Martin Szulecki. All Rights Reserved. 6 | * Copyright (c) 2012 Nikias Bassen. All Rights Reserved. 7 | * Copyright (c) 2010 Joshua Hill. All Rights Reserved. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef IDEVICERESTORE_TSS_H 25 | #define IDEVICERESTORE_TSS_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | /* parameters */ 35 | int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity); 36 | 37 | /* request */ 38 | plist_t tss_request_new(plist_t overrides); 39 | 40 | int tss_request_add_common_tags(plist_t request, plist_t parameters, plist_t overrides); 41 | int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides, struct idevicerestore_client_t* client); 42 | int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides); 43 | int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrides); 44 | 45 | int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters); 46 | int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters); 47 | 48 | /* i/o */ 49 | plist_t tss_request_send(plist_t request, const char* server_url_string); 50 | 51 | /* response */ 52 | int tss_response_get_ap_img4_ticket(plist_t response, unsigned char** ticket, unsigned int* length); 53 | int tss_response_get_ap_ticket(plist_t response, unsigned char** ticket, unsigned int* length); 54 | int tss_response_get_baseband_ticket(plist_t response, unsigned char** ticket, unsigned int* length); 55 | int tss_response_get_path_by_entry(plist_t response, const char* entry, char** path); 56 | int tss_response_get_blob_by_path(plist_t response, const char* path, unsigned char** blob); 57 | int tss_response_get_blob_by_entry(plist_t response, const char* entry, unsigned char** blob); 58 | 59 | /* helpers */ 60 | char* ecid_to_string(uint64_t ecid); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/idevicererestore/ubid_list.h: -------------------------------------------------------------------------------- 1 | #ifndef UBID_LIST_H 2 | #define UBID_LIST_H 3 | 4 | // UniqueBuildID 5 | // s5l8940x 6 | unsigned char n94_841_ubid[] = { 7 | 0x78, 0xc3, 0x14, 0x68, 8 | 0x5a, 0x7e, 0xa2, 0xdf, 9 | 0x8e, 0x30, 0x86, 0x47, 10 | 0x0b, 0x3a, 0xf0, 0xad, 11 | 0x4f, 0x39, 0x5b, 0xad 12 | }; 13 | 14 | unsigned char k93_841_ubid[] = { 15 | 0xb0, 0x0e, 0x40, 0xa6, 16 | 0xfd, 0xc3, 0x90, 0xb6, 17 | 0x2e, 0xac, 0xcb, 0x1e, 18 | 0x7f, 0x1c, 0x20, 0x73, 19 | 0x61, 0x78, 0x7b, 0x0c 20 | }; 21 | 22 | unsigned char k94_841_ubid[] = { 23 | 0x43, 0x94, 0xd1, 0xe8, 24 | 0x01, 0x49, 0x02, 0x3c, 25 | 0x7f, 0xd0, 0xfb, 0xd8, 26 | 0x79, 0x36, 0x27, 0x52, 27 | 0xb4, 0xb9, 0x07, 0xf4 28 | }; 29 | 30 | unsigned char k95_841_ubid[] = { 31 | 0xa4, 0x32, 0x81, 0xc2, 32 | 0x6d, 0x66, 0xeb, 0x2c, 33 | 0xf6, 0xf9, 0xfa, 0x8f, 34 | 0xbe, 0xaa, 0x7d, 0x6c, 35 | 0x36, 0x01, 0xa5, 0xa5 36 | }; 37 | 38 | // s5l8942x 39 | unsigned char k93a_841_ubid[] = { 40 | 0x90, 0x39, 0x82, 0x7d, 41 | 0x37, 0x04, 0x60, 0x7e, 42 | 0x01, 0xcb, 0xc4, 0xcd, 43 | 0x52, 0x11, 0x7c, 0x1c, 44 | 0x1b, 0x1c, 0x2f, 0xb1 45 | }; 46 | 47 | unsigned char n78_841_ubid[] = { 48 | 0x84, 0xa0, 0xb5, 0x64, 49 | 0xd5, 0xdd, 0x55, 0xdf, 50 | 0x24, 0xb6, 0x2d, 0x70, 51 | 0xd9, 0x69, 0x69, 0x0b, 52 | 0x8b, 0x06, 0xdb, 0xc7 53 | }; 54 | 55 | unsigned char p105_841_ubid[] = { 56 | 0x14, 0x9f, 0xfb, 0x70, 57 | 0x61, 0xa1, 0x6c, 0x9d, 58 | 0x35, 0x9b, 0xa7, 0xc0, 59 | 0x02, 0x91, 0x92, 0x4c, 60 | 0x6d, 0xb9, 0x57, 0xda 61 | }; 62 | 63 | unsigned char p106_841_ubid[] = { 64 | 0xcf, 0x89, 0x06, 0xa8, 65 | 0xa6, 0xb6, 0xb9, 0x66, 66 | 0x4d, 0xfb, 0x0f, 0x5e, 67 | 0x44, 0x5f, 0x9b, 0x02, 68 | 0xb3, 0x95, 0xa4, 0x22 69 | }; 70 | 71 | unsigned char p107_841_ubid[] = { 72 | 0xea, 0x4e, 0x9a, 0x78, 73 | 0x92, 0x7a, 0x6e, 0x95, 74 | 0xd9, 0x5b, 0xe3, 0xf7, 75 | 0xa7, 0x53, 0xe6, 0xcb, 76 | 0xd3, 0x6d, 0xb6, 0xe3 77 | }; 78 | 79 | // s5l8945x 80 | unsigned char j1_841_ubid[] = { 81 | 0x45, 0xbc, 0xc0, 0x5d, 82 | 0xe1, 0x60, 0x36, 0xaf, 83 | 0xd8, 0x62, 0x29, 0x8b, 84 | 0xf2, 0xfe, 0xcb, 0xeb, 85 | 0x13, 0xef, 0x23, 0x64 86 | }; 87 | 88 | unsigned char j2_841_ubid[] = { 89 | 0xb3, 0xdb, 0x7e, 0x36, 90 | 0x0a, 0xec, 0xe4, 0x5d, 91 | 0xc6, 0xc3, 0x47, 0x6f, 92 | 0x83, 0x87, 0x15, 0xbe, 93 | 0x08, 0x05, 0x3f, 0xc9 94 | }; 95 | 96 | unsigned char j2a_841_ubid[] = { 97 | 0xe0, 0x14, 0x4c, 0xd9, 98 | 0xa3, 0x7d, 0x2f, 0x96, 99 | 0x41, 0x28, 0x94, 0x66, 100 | 0x4a, 0xea, 0xff, 0x2c, 101 | 0x74, 0x9e, 0x6f, 0x04 102 | }; 103 | 104 | // s5l8950x 105 | unsigned char n41_841_ubid[] = { 106 | 0x3a, 0xb8, 0x69, 0xb7, 107 | 0x56, 0x56, 0x83, 0x0d, 108 | 0xb5, 0x5b, 0xf8, 0xdf, 109 | 0xd4, 0x08, 0xcd, 0x32, 110 | 0x2b, 0x8c, 0x71, 0xfb 111 | }; 112 | 113 | unsigned char n42_841_ubid[] = { 114 | 0xc9, 0xb1, 0xc4, 0xa3, 115 | 0x71, 0x6f, 0xd3, 0x2f, 116 | 0xfa, 0x21, 0x8a, 0x74, 117 | 0x5f, 0x8e, 0x61, 0xc6, 118 | 0xa0, 0xd8, 0xef, 0x33 119 | }; 120 | 121 | // s5l8955x 122 | unsigned char p101_841_ubid[] = { 123 | 0x70, 0x09, 0x37, 0x15, 124 | 0x99, 0x38, 0xd3, 0xc8, 125 | 0xb0, 0xe4, 0x83, 0x22, 126 | 0x48, 0x0b, 0xe3, 0xdb, 127 | 0x58, 0x51, 0x65, 0x61 128 | }; 129 | 130 | unsigned char p102_841_ubid[] = { 131 | 0x28, 0x86, 0xd8, 0x80, 132 | 0xd1, 0x8f, 0xee, 0xa3, 133 | 0xde, 0xe1, 0xcb, 0xf2, 134 | 0x25, 0xb9, 0x57, 0x7a, 135 | 0xf4, 0xa5, 0x46, 0x3b 136 | }; 137 | 138 | unsigned char p103_841_ubid[] = { 139 | 0x02, 0xaf, 0xd3, 0x33, 140 | 0xdf, 0x9f, 0xcd, 0xf0, 141 | 0xa1, 0x4f, 0x21, 0xc8, 142 | 0xde, 0x8b, 0x2d, 0x73, 143 | 0x54, 0x46, 0x1a, 0x41 144 | }; 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /src/xpwn/common/base64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | unsigned char* decodeBase64(char* toDecode, size_t* dataLength) { 9 | uint8_t buffer[4]; 10 | uint8_t charsInBuffer; 11 | unsigned char* curChar; 12 | unsigned char* decodeBuffer; 13 | unsigned int decodeLoc; 14 | unsigned int decodeBufferSize; 15 | uint8_t bytesToDrop; 16 | 17 | curChar = (unsigned char*) toDecode; 18 | charsInBuffer = 0; 19 | 20 | decodeBufferSize = 100; 21 | decodeLoc = 0; 22 | decodeBuffer = (unsigned char*) malloc(decodeBufferSize); 23 | 24 | bytesToDrop = 0; 25 | 26 | while((*curChar) != '\0') { 27 | if((*curChar) >= 'A' && (*curChar) <= 'Z') { 28 | buffer[charsInBuffer] = (*curChar) - 'A'; 29 | charsInBuffer++; 30 | } 31 | 32 | if((*curChar) >= 'a' && (*curChar) <= 'z') { 33 | buffer[charsInBuffer] = ((*curChar) - 'a') + ('Z' - 'A' + 1); 34 | charsInBuffer++; 35 | } 36 | 37 | if((*curChar) >= '0' && (*curChar) <= '9') { 38 | buffer[charsInBuffer] = ((*curChar) - '0') + ('Z' - 'A' + 1) + ('z' - 'a' + 1); 39 | charsInBuffer++; 40 | } 41 | 42 | if((*curChar) == '+') { 43 | buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1); 44 | charsInBuffer++; 45 | } 46 | 47 | if((*curChar) == '/') { 48 | buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 1; 49 | charsInBuffer++; 50 | } 51 | 52 | if((*curChar) == '=') { 53 | bytesToDrop++; 54 | } 55 | 56 | if(charsInBuffer == 4) { 57 | charsInBuffer = 0; 58 | 59 | if((decodeLoc + 3) >= decodeBufferSize) { 60 | decodeBufferSize <<= 1; 61 | decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize); 62 | } 63 | decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) + ((buffer[1] >> 4) & 0x3F); 64 | decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) + ((buffer[2] >> 2) & 0x0F); 65 | decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) + (buffer[3] & 0x3F); 66 | 67 | decodeLoc += 3; 68 | buffer[0] = 0; 69 | buffer[1] = 0; 70 | buffer[2] = 0; 71 | buffer[3] = 0; 72 | } 73 | 74 | curChar++; 75 | } 76 | 77 | if(bytesToDrop != 0) { 78 | if((decodeLoc + 3) >= decodeBufferSize) { 79 | decodeBufferSize <<= 1; 80 | decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize); 81 | } 82 | 83 | decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) | ((buffer[1] >> 4) & 0x3F); 84 | 85 | if(bytesToDrop <= 2) 86 | decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) | ((buffer[2] >> 2) & 0x0F); 87 | 88 | if(bytesToDrop <= 1) 89 | decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) | (buffer[3] & 0x3F); 90 | 91 | *dataLength = decodeLoc + 3 - bytesToDrop; 92 | } else { 93 | *dataLength = decodeLoc; 94 | } 95 | 96 | return decodeBuffer; 97 | } 98 | 99 | void writeBase64(AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width) { 100 | char* buffer; 101 | buffer = convertBase64(data, dataLength, tabLength, width); 102 | file->write(file, buffer, strlen(buffer)); 103 | free(buffer); 104 | } 105 | 106 | #define CHECK_BUFFER_SIZE() \ 107 | if(pos == bufferSize) { \ 108 | bufferSize <<= 1; \ 109 | buffer = (unsigned char*) realloc(buffer, bufferSize); \ 110 | } 111 | 112 | #define CHECK_LINE_END_STRING() \ 113 | CHECK_BUFFER_SIZE() \ 114 | if(width == lineLength) { \ 115 | buffer[pos++] = '\n'; \ 116 | CHECK_BUFFER_SIZE() \ 117 | for(j = 0; j < tabLength; j++) { \ 118 | buffer[pos++] = '\t'; \ 119 | CHECK_BUFFER_SIZE() \ 120 | } \ 121 | lineLength = 0; \ 122 | } else { \ 123 | lineLength++; \ 124 | } 125 | 126 | char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width) { 127 | const char* dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 128 | 129 | unsigned char* buffer; 130 | size_t pos; 131 | size_t bufferSize; 132 | int i, j; 133 | int lineLength; 134 | 135 | bufferSize = 100; 136 | buffer = (unsigned char*) malloc(bufferSize); 137 | pos = 0; 138 | lineLength = 0; 139 | 140 | for(i = 0; i < tabLength; i++) { 141 | CHECK_BUFFER_SIZE() 142 | buffer[pos++] = '\t'; 143 | } 144 | i = 0; 145 | while(dataLength >= 3) { 146 | dataLength -= 3; 147 | buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F]; 148 | CHECK_LINE_END_STRING(); 149 | buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F]; 150 | CHECK_LINE_END_STRING(); 151 | buffer[pos++] = dictionary[(((data[i+1] << 2) & 0x3C) | ((data[i+2] >> 6) & 0x03)) & 0x03F]; 152 | CHECK_LINE_END_STRING(); 153 | buffer[pos++] = dictionary[data[i+2] & 0x3F]; 154 | CHECK_LINE_END_STRING(); 155 | i += 3; 156 | } 157 | 158 | if(dataLength == 2) { 159 | buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F]; 160 | CHECK_LINE_END_STRING(); 161 | buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F]; 162 | CHECK_LINE_END_STRING(); 163 | buffer[pos++] = dictionary[(data[i+1] << 2) & 0x3C]; 164 | CHECK_LINE_END_STRING(); 165 | buffer[pos++] = '='; 166 | } else if(dataLength == 1) { 167 | buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F]; 168 | CHECK_LINE_END_STRING(); 169 | buffer[pos++] = dictionary[(data[i] << 4) & 0x30]; 170 | CHECK_LINE_END_STRING(); 171 | buffer[pos++] = '='; 172 | CHECK_LINE_END_STRING(); 173 | buffer[pos++] = '='; 174 | } 175 | 176 | CHECK_BUFFER_SIZE(); 177 | buffer[pos++] = '\n'; 178 | 179 | CHECK_BUFFER_SIZE(); 180 | buffer[pos++] = '\0'; 181 | 182 | return (char*) buffer; 183 | } 184 | -------------------------------------------------------------------------------- /src/xpwn/dmg/udif.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | void flipUDIFChecksum(UDIFChecksum* o, char out) { 8 | int i; 9 | 10 | FLIPENDIAN(o->type); 11 | 12 | if(out) { 13 | for(i = 0; i < o->size; i++) { 14 | FLIPENDIAN(o->data[i]); 15 | } 16 | FLIPENDIAN(o->size); 17 | } else { 18 | FLIPENDIAN(o->size); 19 | for(i = 0; i < o->size; i++) { 20 | FLIPENDIAN(o->data[i]); 21 | } 22 | } 23 | } 24 | 25 | void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o) { 26 | int i; 27 | 28 | o->type = readUInt32(file); 29 | o->size = readUInt32(file); 30 | 31 | for(i = 0; i < 0x20; i++) { 32 | o->data[i] = readUInt32(file); 33 | } 34 | } 35 | 36 | void writeUDIFChecksum(AbstractFile* file, UDIFChecksum* o) { 37 | int i; 38 | 39 | writeUInt32(file, o->type); 40 | writeUInt32(file, o->size); 41 | 42 | for(i = 0; i < o->size; i++) { 43 | writeUInt32(file, o->data[i]); 44 | } 45 | } 46 | 47 | void readUDIFID(AbstractFile* file, UDIFID* o) { 48 | o->data4 = readUInt32(file); FLIPENDIAN(o->data4); 49 | o->data3 = readUInt32(file); FLIPENDIAN(o->data3); 50 | o->data2 = readUInt32(file); FLIPENDIAN(o->data2); 51 | o->data1 = readUInt32(file); FLIPENDIAN(o->data1); 52 | } 53 | 54 | void writeUDIFID(AbstractFile* file, UDIFID* o) { 55 | FLIPENDIAN(o->data4); writeUInt32(file, o->data4); FLIPENDIAN(o->data4); 56 | FLIPENDIAN(o->data3); writeUInt32(file, o->data3); FLIPENDIAN(o->data3); 57 | FLIPENDIAN(o->data2); writeUInt32(file, o->data2); FLIPENDIAN(o->data2); 58 | FLIPENDIAN(o->data1); writeUInt32(file, o->data1); FLIPENDIAN(o->data1); 59 | } 60 | 61 | int readUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o, int die) { 62 | o->fUDIFSignature = readUInt32(file); 63 | 64 | if (!die && o->fUDIFSignature != 0x6B6F6C79) return -1; 65 | ASSERT(o->fUDIFSignature == 0x6B6F6C79, "readUDIFResourceFile - signature incorrect"); 66 | 67 | o->fUDIFVersion = readUInt32(file); 68 | o->fUDIFHeaderSize = readUInt32(file); 69 | o->fUDIFFlags = readUInt32(file); 70 | 71 | o->fUDIFRunningDataForkOffset = readUInt64(file); 72 | o->fUDIFDataForkOffset = readUInt64(file); 73 | o->fUDIFDataForkLength = readUInt64(file); 74 | o->fUDIFRsrcForkOffset = readUInt64(file); 75 | o->fUDIFRsrcForkLength = readUInt64(file); 76 | 77 | o->fUDIFSegmentNumber = readUInt32(file); 78 | o->fUDIFSegmentCount = readUInt32(file); 79 | readUDIFID(file, &(o->fUDIFSegmentID)); 80 | 81 | readUDIFChecksum(file, &(o->fUDIFDataForkChecksum)); 82 | 83 | o->fUDIFXMLOffset = readUInt64(file); 84 | o->fUDIFXMLLength = readUInt64(file); 85 | 86 | ASSERT(file->read(file, &(o->reserved1), 0x78) == 0x78, "fread"); 87 | 88 | readUDIFChecksum(file, &(o->fUDIFMasterChecksum)); 89 | 90 | o->fUDIFImageVariant = readUInt32(file); 91 | o->fUDIFSectorCount = readUInt64(file); 92 | 93 | o->reserved2 = readUInt32(file); 94 | o->reserved3 = readUInt32(file); 95 | o->reserved4 = readUInt32(file); 96 | return 0; 97 | } 98 | 99 | void writeUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o) { 100 | writeUInt32(file, o->fUDIFSignature); 101 | writeUInt32(file, o->fUDIFVersion); 102 | writeUInt32(file, o->fUDIFHeaderSize); 103 | writeUInt32(file, o->fUDIFFlags); 104 | 105 | writeUInt64(file, o->fUDIFRunningDataForkOffset); 106 | writeUInt64(file, o->fUDIFDataForkOffset); 107 | writeUInt64(file, o->fUDIFDataForkLength); 108 | writeUInt64(file, o->fUDIFRsrcForkOffset); 109 | writeUInt64(file, o->fUDIFRsrcForkLength); 110 | 111 | writeUInt32(file, o->fUDIFSegmentNumber); 112 | writeUInt32(file, o->fUDIFSegmentCount); 113 | writeUDIFID(file, &(o->fUDIFSegmentID)); 114 | 115 | writeUDIFChecksum(file, &(o->fUDIFDataForkChecksum)); 116 | 117 | writeUInt64(file, o->fUDIFXMLOffset); 118 | writeUInt64(file, o->fUDIFXMLLength); 119 | 120 | ASSERT(file->write(file, &(o->reserved1), 0x78) == 0x78, "fwrite"); 121 | 122 | writeUDIFChecksum(file, &(o->fUDIFMasterChecksum)); 123 | 124 | writeUInt32(file, o->fUDIFImageVariant); 125 | writeUInt64(file, o->fUDIFSectorCount); 126 | 127 | writeUInt32(file, o->reserved2); 128 | writeUInt32(file, o->reserved3); 129 | writeUInt32(file, o->reserved4); 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/xpwn/hfs/extents.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static inline void flipExtentDescriptor(HFSPlusExtentDescriptor* extentDescriptor) { 6 | FLIPENDIAN(extentDescriptor->startBlock); 7 | FLIPENDIAN(extentDescriptor->blockCount); 8 | } 9 | 10 | void flipExtentRecord(HFSPlusExtentRecord* extentRecord) { 11 | HFSPlusExtentDescriptor *extentDescriptor; 12 | extentDescriptor = (HFSPlusExtentDescriptor*)extentRecord; 13 | 14 | flipExtentDescriptor(&extentDescriptor[0]); 15 | flipExtentDescriptor(&extentDescriptor[1]); 16 | flipExtentDescriptor(&extentDescriptor[2]); 17 | flipExtentDescriptor(&extentDescriptor[3]); 18 | flipExtentDescriptor(&extentDescriptor[4]); 19 | flipExtentDescriptor(&extentDescriptor[5]); 20 | flipExtentDescriptor(&extentDescriptor[6]); 21 | flipExtentDescriptor(&extentDescriptor[7]); 22 | } 23 | 24 | static int extentCompare(BTKey* vLeft, BTKey* vRight) { 25 | HFSPlusExtentKey* left; 26 | HFSPlusExtentKey* right; 27 | 28 | left = (HFSPlusExtentKey*) vLeft; 29 | right =(HFSPlusExtentKey*) vRight; 30 | 31 | if(left->forkType < right->forkType) { 32 | return -1; 33 | } else if(left->forkType > right->forkType) { 34 | return 1; 35 | } else { 36 | if(left->fileID < right->fileID) { 37 | return -1; 38 | } else if(left->fileID > right->fileID) { 39 | return 1; 40 | } else { 41 | if(left->startBlock < right->startBlock) { 42 | return -1; 43 | } else if(left->startBlock > right->startBlock) { 44 | return 1; 45 | } else { 46 | /* do a safety check on key length. Otherwise, bad things may happen later on when we try to add or remove with this key */ 47 | if(left->keyLength == right->keyLength) { 48 | return 0; 49 | } else if(left->keyLength < right->keyLength) { 50 | return -1; 51 | } else { 52 | return 1; 53 | } 54 | return 0; 55 | } 56 | } 57 | } 58 | } 59 | 60 | static BTKey* extentKeyRead(off_t offset, io_func* io) { 61 | HFSPlusExtentKey* key; 62 | 63 | key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey)); 64 | 65 | if(!READ(io, offset, sizeof(HFSPlusExtentKey), key)) 66 | return NULL; 67 | 68 | FLIPENDIAN(key->keyLength); 69 | FLIPENDIAN(key->forkType); 70 | FLIPENDIAN(key->fileID); 71 | FLIPENDIAN(key->startBlock); 72 | 73 | return (BTKey*)key; 74 | } 75 | 76 | static int extentKeyWrite(off_t offset, BTKey* toWrite, io_func* io) { 77 | HFSPlusExtentKey* key; 78 | 79 | key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey)); 80 | 81 | memcpy(key, toWrite, sizeof(HFSPlusExtentKey)); 82 | 83 | FLIPENDIAN(key->keyLength); 84 | FLIPENDIAN(key->forkType); 85 | FLIPENDIAN(key->fileID); 86 | FLIPENDIAN(key->startBlock); 87 | 88 | if(!WRITE(io, offset, sizeof(HFSPlusExtentKey), key)) 89 | return FALSE; 90 | 91 | free(key); 92 | 93 | return TRUE; 94 | } 95 | 96 | static void extentKeyPrint(BTKey* toPrint) { 97 | HFSPlusExtentKey* key; 98 | 99 | key = (HFSPlusExtentKey*)toPrint; 100 | 101 | printf("extent%d:%d:%d", key->forkType, key->fileID, key->startBlock); 102 | } 103 | 104 | static BTKey* extentDataRead(off_t offset, io_func* io) { 105 | HFSPlusExtentRecord* record; 106 | 107 | record = (HFSPlusExtentRecord*) malloc(sizeof(HFSPlusExtentRecord)); 108 | 109 | if(!READ(io, offset, sizeof(HFSPlusExtentRecord), record)) 110 | return NULL; 111 | 112 | flipExtentRecord(record); 113 | 114 | return (BTKey*)record; 115 | } 116 | 117 | BTree* openExtentsTree(io_func* file) { 118 | return openBTree(file, &extentCompare, &extentKeyRead, &extentKeyWrite, &extentKeyPrint, &extentDataRead); 119 | } 120 | -------------------------------------------------------------------------------- /src/xpwn/hfs/flatfile.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int flatFileRead(io_func* io, off_t location, size_t size, void *buffer) { 5 | FILE* file; 6 | file = (FILE*) io->data; 7 | 8 | if(size == 0) { 9 | return TRUE; 10 | } 11 | 12 | //printf("%d %d\n", location, size); fflush(stdout); 13 | 14 | if(fseeko(file, location, SEEK_SET) != 0) { 15 | perror("fseek"); 16 | return FALSE; 17 | } 18 | 19 | if(fread(buffer, size, 1, file) != 1) { 20 | perror("fread"); 21 | return FALSE; 22 | } else { 23 | return TRUE; 24 | } 25 | } 26 | 27 | static int flatFileWrite(io_func* io, off_t location, size_t size, void *buffer) { 28 | FILE* file; 29 | 30 | /*int i; 31 | 32 | printf("write: %lld %d - ", location, size); fflush(stdout); 33 | 34 | for(i = 0; i < size; i++) { 35 | printf("%x ", ((unsigned char*)buffer)[i]); 36 | fflush(stdout); 37 | } 38 | printf("\n"); fflush(stdout);*/ 39 | 40 | if(size == 0) { 41 | return TRUE; 42 | } 43 | 44 | file = (FILE*) io->data; 45 | 46 | if(fseeko(file, location, SEEK_SET) != 0) { 47 | perror("fseek"); 48 | return FALSE; 49 | } 50 | 51 | if(fwrite(buffer, size, 1, file) != 1) { 52 | perror("fwrite"); 53 | return FALSE; 54 | } else { 55 | return TRUE; 56 | } 57 | 58 | return TRUE; 59 | } 60 | 61 | static void closeFlatFile(io_func* io) { 62 | FILE* file; 63 | 64 | file = (FILE*) io->data; 65 | 66 | fclose(file); 67 | free(io); 68 | } 69 | 70 | io_func* openFlatFile(const char* fileName) { 71 | io_func* io; 72 | 73 | io = (io_func*) malloc(sizeof(io_func)); 74 | io->data = fopen(fileName, "rb+"); 75 | 76 | if(io->data == NULL) { 77 | perror("fopen"); 78 | return NULL; 79 | } 80 | 81 | io->read = &flatFileRead; 82 | io->write = &flatFileWrite; 83 | io->close = &closeFlatFile; 84 | 85 | return io; 86 | } 87 | 88 | io_func* openFlatFileRO(const char* fileName) { 89 | io_func* io; 90 | 91 | io = (io_func*) malloc(sizeof(io_func)); 92 | io->data = fopen(fileName, "rb"); 93 | 94 | if(io->data == NULL) { 95 | perror("fopen"); 96 | return NULL; 97 | } 98 | 99 | io->read = &flatFileRead; 100 | io->write = &flatFileWrite; 101 | io->close = &closeFlatFile; 102 | 103 | return io; 104 | } 105 | -------------------------------------------------------------------------------- /src/xpwn/hfs/utility.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void hfs_panic(const char* hfs_panicString) { 6 | fprintf(stderr, "%s\n", hfs_panicString); 7 | exit(1); 8 | } 9 | 10 | void printUnicode(HFSUniStr255* str) { 11 | int i; 12 | 13 | for(i = 0; i < str->length; i++) { 14 | printf("%c", (char)(str->unicode[i] & 0xff)); 15 | } 16 | } 17 | 18 | char* unicodeToAscii(HFSUniStr255* str) { 19 | int i; 20 | char* toReturn; 21 | 22 | toReturn = (char*) malloc(sizeof(char) * (str->length + 1)); 23 | 24 | for(i = 0; i < str->length; i++) { 25 | toReturn[i] = (char)(str->unicode[i] & 0xff); 26 | } 27 | toReturn[i] = '\0'; 28 | 29 | return toReturn; 30 | } 31 | -------------------------------------------------------------------------------- /src/xpwn/hfs/volume.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void flipForkData(HFSPlusForkData* forkData) { 6 | FLIPENDIAN(forkData->logicalSize); 7 | FLIPENDIAN(forkData->clumpSize); 8 | FLIPENDIAN(forkData->totalBlocks); 9 | 10 | flipExtentRecord(&forkData->extents); 11 | } 12 | 13 | static HFSPlusVolumeHeader* readVolumeHeader(io_func* io, off_t offset) { 14 | HFSPlusVolumeHeader* volumeHeader; 15 | 16 | volumeHeader = (HFSPlusVolumeHeader*) malloc(sizeof(HFSPlusVolumeHeader)); 17 | 18 | if(!(READ(io, offset, sizeof(HFSPlusVolumeHeader), volumeHeader))) 19 | return NULL; 20 | 21 | FLIPENDIAN(volumeHeader->signature); 22 | FLIPENDIAN(volumeHeader->version); 23 | FLIPENDIAN(volumeHeader->attributes); 24 | FLIPENDIAN(volumeHeader->lastMountedVersion); 25 | FLIPENDIAN(volumeHeader->journalInfoBlock); 26 | FLIPENDIAN(volumeHeader->createDate); 27 | FLIPENDIAN(volumeHeader->modifyDate); 28 | FLIPENDIAN(volumeHeader->backupDate); 29 | FLIPENDIAN(volumeHeader->checkedDate); 30 | FLIPENDIAN(volumeHeader->fileCount); 31 | FLIPENDIAN(volumeHeader->folderCount); 32 | FLIPENDIAN(volumeHeader->blockSize); 33 | FLIPENDIAN(volumeHeader->totalBlocks); 34 | FLIPENDIAN(volumeHeader->freeBlocks); 35 | FLIPENDIAN(volumeHeader->nextAllocation); 36 | FLIPENDIAN(volumeHeader->rsrcClumpSize); 37 | FLIPENDIAN(volumeHeader->dataClumpSize); 38 | FLIPENDIAN(volumeHeader->nextCatalogID); 39 | FLIPENDIAN(volumeHeader->writeCount); 40 | FLIPENDIAN(volumeHeader->encodingsBitmap); 41 | 42 | 43 | flipForkData(&volumeHeader->allocationFile); 44 | flipForkData(&volumeHeader->extentsFile); 45 | flipForkData(&volumeHeader->catalogFile); 46 | flipForkData(&volumeHeader->attributesFile); 47 | flipForkData(&volumeHeader->startupFile); 48 | 49 | return volumeHeader; 50 | } 51 | 52 | static int writeVolumeHeader(io_func* io, HFSPlusVolumeHeader* volumeHeaderToWrite, off_t offset) { 53 | HFSPlusVolumeHeader* volumeHeader; 54 | 55 | volumeHeader = (HFSPlusVolumeHeader*) malloc(sizeof(HFSPlusVolumeHeader)); 56 | memcpy(volumeHeader, volumeHeaderToWrite, sizeof(HFSPlusVolumeHeader)); 57 | 58 | FLIPENDIAN(volumeHeader->signature); 59 | FLIPENDIAN(volumeHeader->version); 60 | FLIPENDIAN(volumeHeader->attributes); 61 | FLIPENDIAN(volumeHeader->lastMountedVersion); 62 | FLIPENDIAN(volumeHeader->journalInfoBlock); 63 | FLIPENDIAN(volumeHeader->createDate); 64 | FLIPENDIAN(volumeHeader->modifyDate); 65 | FLIPENDIAN(volumeHeader->backupDate); 66 | FLIPENDIAN(volumeHeader->checkedDate); 67 | FLIPENDIAN(volumeHeader->fileCount); 68 | FLIPENDIAN(volumeHeader->folderCount); 69 | FLIPENDIAN(volumeHeader->blockSize); 70 | FLIPENDIAN(volumeHeader->totalBlocks); 71 | FLIPENDIAN(volumeHeader->freeBlocks); 72 | FLIPENDIAN(volumeHeader->nextAllocation); 73 | FLIPENDIAN(volumeHeader->rsrcClumpSize); 74 | FLIPENDIAN(volumeHeader->dataClumpSize); 75 | FLIPENDIAN(volumeHeader->nextCatalogID); 76 | FLIPENDIAN(volumeHeader->writeCount); 77 | FLIPENDIAN(volumeHeader->encodingsBitmap); 78 | 79 | 80 | flipForkData(&volumeHeader->allocationFile); 81 | flipForkData(&volumeHeader->extentsFile); 82 | flipForkData(&volumeHeader->catalogFile); 83 | flipForkData(&volumeHeader->attributesFile); 84 | flipForkData(&volumeHeader->startupFile); 85 | 86 | if(!(WRITE(io, offset, sizeof(HFSPlusVolumeHeader), volumeHeader))) 87 | return FALSE; 88 | 89 | free(volumeHeader); 90 | 91 | return TRUE; 92 | } 93 | 94 | int updateVolume(Volume* volume) { 95 | ASSERT(writeVolumeHeader(volume->image, volume->volumeHeader, 96 | ((off_t)volume->volumeHeader->totalBlocks * (off_t)volume->volumeHeader->blockSize) - 1024), "writeVolumeHeader"); 97 | return writeVolumeHeader(volume->image, volume->volumeHeader, 1024); 98 | } 99 | 100 | Volume* openVolume(io_func* io) { 101 | Volume* volume; 102 | io_func* file; 103 | 104 | volume = (Volume*) malloc(sizeof(Volume)); 105 | volume->image = io; 106 | volume->extentsTree = NULL; 107 | 108 | volume->volumeHeader = readVolumeHeader(io, 1024); 109 | if(volume->volumeHeader == NULL) { 110 | free(volume); 111 | return NULL; 112 | } 113 | 114 | file = openRawFile(kHFSExtentsFileID, &volume->volumeHeader->extentsFile, NULL, volume); 115 | if(file == NULL) { 116 | free(volume->volumeHeader); 117 | free(volume); 118 | return NULL; 119 | } 120 | 121 | volume->extentsTree = openExtentsTree(file); 122 | if(volume->extentsTree == NULL) { 123 | free(volume->volumeHeader); 124 | free(volume); 125 | return NULL; 126 | } 127 | 128 | file = openRawFile(kHFSCatalogFileID, &volume->volumeHeader->catalogFile, NULL, volume); 129 | if(file == NULL) { 130 | closeBTree(volume->extentsTree); 131 | free(volume->volumeHeader); 132 | free(volume); 133 | return NULL; 134 | } 135 | 136 | volume->catalogTree = openCatalogTree(file); 137 | if(volume->catalogTree == NULL) { 138 | closeBTree(volume->extentsTree); 139 | free(volume->volumeHeader); 140 | free(volume); 141 | return NULL; 142 | } 143 | 144 | volume->allocationFile = openRawFile(kHFSAllocationFileID, &volume->volumeHeader->allocationFile, NULL, volume); 145 | if(volume->allocationFile == NULL) { 146 | closeBTree(volume->catalogTree); 147 | closeBTree(volume->extentsTree); 148 | free(volume->volumeHeader); 149 | free(volume); 150 | return NULL; 151 | } 152 | 153 | volume->attrTree = NULL; 154 | file = openRawFile(kHFSAttributesFileID, &volume->volumeHeader->attributesFile, NULL, volume); 155 | if(file != NULL) { 156 | volume->attrTree = openAttributesTree(file); 157 | if(!volume->attrTree) { 158 | CLOSE(file); 159 | } 160 | } 161 | 162 | volume->metadataDir = getMetadataDirectoryID(volume); 163 | 164 | return volume; 165 | } 166 | 167 | void closeVolume(Volume *volume) { 168 | if(volume->attrTree) 169 | closeBTree(volume->attrTree); 170 | 171 | CLOSE(volume->allocationFile); 172 | closeBTree(volume->catalogTree); 173 | closeBTree(volume->extentsTree); 174 | free(volume->volumeHeader); 175 | free(volume); 176 | } 177 | -------------------------------------------------------------------------------- /src/xpwn/include/abstractfile.h: -------------------------------------------------------------------------------- 1 | #ifndef ABSTRACTFILE_H 2 | #define ABSTRACTFILE_H 3 | 4 | #include "common.h" 5 | #include 6 | 7 | typedef struct AbstractFile AbstractFile; 8 | typedef struct AbstractFile2 AbstractFile2; 9 | 10 | typedef size_t (*WriteFunc)(AbstractFile* file, const void* data, size_t len); 11 | typedef size_t (*ReadFunc)(AbstractFile* file, void* data, size_t len); 12 | typedef int (*SeekFunc)(AbstractFile* file, off_t offset); 13 | typedef off_t (*TellFunc)(AbstractFile* file); 14 | typedef void (*CloseFunc)(AbstractFile* file); 15 | typedef off_t (*GetLengthFunc)(AbstractFile* file); 16 | typedef void (*SetKeyFunc)(AbstractFile2* file, const unsigned int* key, const unsigned int* iv); 17 | 18 | typedef enum AbstractFileType { 19 | AbstractFileTypeFile, 20 | AbstractFileType8900, 21 | AbstractFileTypeImg2, 22 | AbstractFileTypeImg3, 23 | AbstractFileTypeLZSS, 24 | AbstractFileTypeIBootIM, 25 | AbstractFileTypeMem, 26 | AbstractFileTypeMemFile, 27 | AbstractFileTypeDummy 28 | } AbstractFileType; 29 | 30 | struct AbstractFile { 31 | void* data; 32 | WriteFunc write; 33 | ReadFunc read; 34 | SeekFunc seek; 35 | TellFunc tell; 36 | GetLengthFunc getLength; 37 | CloseFunc close; 38 | AbstractFileType type; 39 | }; 40 | 41 | struct AbstractFile2 { 42 | AbstractFile super; 43 | SetKeyFunc setKey; 44 | }; 45 | 46 | 47 | typedef struct { 48 | size_t offset; 49 | void** buffer; 50 | size_t bufferSize; 51 | } MemWrapperInfo; 52 | 53 | typedef struct { 54 | size_t offset; 55 | void** buffer; 56 | size_t* bufferSize; 57 | size_t actualBufferSize; 58 | } MemFileWrapperInfo; 59 | 60 | #ifdef __cplusplus 61 | extern "C" { 62 | #endif 63 | AbstractFile* createAbstractFileFromFile(FILE* file); 64 | AbstractFile* createAbstractFileFromDummy(); 65 | AbstractFile* createAbstractFileFromMemory(void** buffer, size_t size); 66 | AbstractFile* createAbstractFileFromMemoryFile(void** buffer, size_t* size); 67 | AbstractFile* createAbstractFileFromMemoryFileBuffer(void** buffer, size_t* size, size_t actualBufferSize); 68 | void abstractFilePrint(AbstractFile* file, const char* format, ...); 69 | io_func* IOFuncFromAbstractFile(AbstractFile* file); 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /src/xpwn/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef WIN32 11 | #define fseeko fseeko64 12 | #define ftello ftello64 13 | #define off_t off64_t 14 | #define mkdir(x, y) mkdir(x) 15 | #define PATH_SEPARATOR "\\" 16 | #else 17 | #define PATH_SEPARATOR "/" 18 | #endif 19 | 20 | #define TRUE 1 21 | #define FALSE 0 22 | 23 | #define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x)) 24 | #define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x)) 25 | 26 | #define IS_BIG_ENDIAN 0 27 | #define IS_LITTLE_ENDIAN 1 28 | 29 | #define TIME_OFFSET_FROM_UNIX 2082844800L 30 | #define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX) 31 | #define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX) 32 | 33 | #define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s:%d: %s\n", __FILE__, __LINE__, m); perror("error"); fflush(stderr); exit(1); } 34 | 35 | extern char endianness; 36 | 37 | static inline void flipEndian(unsigned char* x, int length) { 38 | int i; 39 | unsigned char tmp; 40 | 41 | if(endianness == IS_BIG_ENDIAN) { 42 | return; 43 | } else { 44 | for(i = 0; i < (length / 2); i++) { 45 | tmp = x[i]; 46 | x[i] = x[length - i - 1]; 47 | x[length - i - 1] = tmp; 48 | } 49 | } 50 | } 51 | 52 | static inline void flipEndianLE(unsigned char* x, int length) { 53 | int i; 54 | unsigned char tmp; 55 | 56 | if(endianness == IS_LITTLE_ENDIAN) { 57 | return; 58 | } else { 59 | for(i = 0; i < (length / 2); i++) { 60 | tmp = x[i]; 61 | x[i] = x[length - i - 1]; 62 | x[length - i - 1] = tmp; 63 | } 64 | } 65 | } 66 | 67 | static inline void hexToBytes(const char* hex, uint8_t** buffer, size_t* bytes) { 68 | *bytes = strlen(hex) / 2; 69 | *buffer = (uint8_t*) malloc(*bytes); 70 | size_t i; 71 | for(i = 0; i < *bytes; i++) { 72 | uint32_t byte; 73 | sscanf(hex, "%2x", &byte); 74 | (*buffer)[i] = byte; 75 | hex += 2; 76 | } 77 | } 78 | 79 | static inline void hexToInts(const char* hex, unsigned int** buffer, size_t* bytes) { 80 | *bytes = strlen(hex) / 2; 81 | *buffer = (unsigned int*) malloc((*bytes) * sizeof(int)); 82 | size_t i; 83 | for(i = 0; i < *bytes; i++) { 84 | sscanf(hex, "%2x", &((*buffer)[i])); 85 | hex += 2; 86 | } 87 | } 88 | 89 | struct io_func_struct; 90 | 91 | typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer); 92 | typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer); 93 | typedef void (*closeFunc)(struct io_func_struct* io); 94 | 95 | typedef struct io_func_struct { 96 | void* data; 97 | readFunc read; 98 | writeFunc write; 99 | closeFunc close; 100 | } io_func; 101 | 102 | struct AbstractFile; 103 | 104 | unsigned char* decodeBase64(char* toDecode, size_t* dataLength); 105 | void writeBase64(struct AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width); 106 | char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width); 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/xpwn/include/dmg/dmgfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dmgfile.h 3 | * libdmg-hfsplus 4 | * 5 | */ 6 | 7 | #include 8 | 9 | io_func* openDmgFile(AbstractFile* dmg); 10 | io_func* openDmgFilePartition(AbstractFile* dmg, int partition); 11 | 12 | typedef struct DMG { 13 | AbstractFile* dmg; 14 | ResourceKey* resources; 15 | uint32_t numBLKX; 16 | BLKXTable** blkx; 17 | void* runData; 18 | uint64_t runStart; 19 | uint64_t runEnd; 20 | uint64_t offset; 21 | } DMG; 22 | -------------------------------------------------------------------------------- /src/xpwn/include/dmg/dmglib.h: -------------------------------------------------------------------------------- 1 | #ifndef DMGLIB_H 2 | #define DMGLIB_H 3 | 4 | #include 5 | #include "abstractfile.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum); 11 | int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, unsigned int BlockSize); 12 | 13 | int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut); 14 | int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut); 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/xpwn/include/dmg/filevault.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEVAULT_H 2 | #define FILEVAULT_H 3 | 4 | #include 5 | #include "dmg.h" 6 | 7 | #ifdef HAVE_CRYPT 8 | 9 | #include 10 | #include 11 | 12 | #define FILEVAULT_CIPHER_KEY_LENGTH 16 13 | #define FILEVAULT_CIPHER_BLOCKSIZE 16 14 | #define FILEVAULT_CHUNK_SIZE 4096 15 | #define FILEVAULT_PBKDF2_ITER_COUNT 1000 16 | #define FILEVAULT_MSGDGST_LENGTH 20 17 | 18 | /* 19 | * Information about the FileVault format was yoinked from vfdecrypt, which was written by Ralf-Philipp Weinmann , 20 | * Jacob Appelbaum , and Christian Fromme 21 | */ 22 | 23 | #define FILEVAULT_V2_SIGNATURE 0x656e637263647361ULL 24 | 25 | typedef struct FileVaultV1Header { 26 | uint8_t padding1[48]; 27 | uint32_t kdfIterationCount; 28 | uint32_t kdfSaltLen; 29 | uint8_t kdfSalt[48]; 30 | uint8_t unwrapIV[0x20]; 31 | uint32_t wrappedAESKeyLen; 32 | uint8_t wrappedAESKey[296]; 33 | uint32_t wrappedHMACSHA1KeyLen; 34 | uint8_t wrappedHMACSHA1Key[300]; 35 | uint32_t integrityKeyLen; 36 | uint8_t integrityKey[48]; 37 | uint8_t padding2[484]; 38 | } __attribute__((__packed__)) FileVaultV1Header; 39 | 40 | typedef struct FileVaultV2Header { 41 | uint64_t signature; 42 | uint32_t version; 43 | uint32_t encIVSize; 44 | uint32_t unk1; 45 | uint32_t unk2; 46 | uint32_t unk3; 47 | uint32_t unk4; 48 | uint32_t unk5; 49 | UDIFID uuid; 50 | uint32_t blockSize; 51 | uint64_t dataSize; 52 | uint64_t dataOffset; 53 | uint8_t padding[0x260]; 54 | uint32_t kdfAlgorithm; 55 | uint32_t kdfPRNGAlgorithm; 56 | uint32_t kdfIterationCount; 57 | uint32_t kdfSaltLen; 58 | uint8_t kdfSalt[0x20]; 59 | uint32_t blobEncIVSize; 60 | uint8_t blobEncIV[0x20]; 61 | uint32_t blobEncKeyBits; 62 | uint32_t blobEncAlgorithm; 63 | uint32_t blobEncPadding; 64 | uint32_t blobEncMode; 65 | uint32_t encryptedKeyblobSize; 66 | uint8_t encryptedKeyblob[0x30]; 67 | } __attribute__((__packed__)) FileVaultV2Header; 68 | 69 | typedef struct FileVaultInfo { 70 | union { 71 | FileVaultV1Header v1; 72 | FileVaultV2Header v2; 73 | } header; 74 | 75 | uint8_t version; 76 | uint64_t dataOffset; 77 | uint64_t dataSize; 78 | uint32_t blockSize; 79 | 80 | AbstractFile* file; 81 | 82 | //HMAC_CTX hmacCTX; 83 | HMAC_CTX* hmacCTX; 84 | AES_KEY aesKey; 85 | AES_KEY aesEncKey; 86 | 87 | off_t offset; 88 | 89 | uint32_t curChunk; 90 | unsigned char chunk[FILEVAULT_CHUNK_SIZE]; 91 | 92 | char dirty; 93 | char headerDirty; 94 | } FileVaultInfo; 95 | #endif 96 | 97 | AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key); 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/xpwn/include/hfs/hfscompress.h: -------------------------------------------------------------------------------- 1 | #ifndef HFSCOMPRESS_H 2 | #define HFSCOMPRESS_H 3 | 4 | #include 5 | #include "common.h" 6 | 7 | #define CMPFS_MAGIC 0x636D7066 8 | 9 | typedef struct HFSPlusDecmpfs { 10 | uint32_t magic; 11 | uint32_t flags; 12 | uint64_t size; 13 | uint8_t data[0]; 14 | } __attribute__ ((packed)) HFSPlusDecmpfs; 15 | 16 | typedef struct HFSPlusCmpfRsrcHead { 17 | uint32_t headerSize; 18 | uint32_t totalSize; 19 | uint32_t dataSize; 20 | uint32_t flags; 21 | } __attribute__ ((packed)) HFSPlusCmpfRsrcHead; 22 | 23 | typedef struct HFSPlusCmpfRsrcBlock { 24 | uint32_t offset; 25 | uint32_t size; 26 | } __attribute__ ((packed)) HFSPlusCmpfRsrcBlock; 27 | 28 | typedef struct HFSPlusCmpfRsrcBlockHead { 29 | uint32_t dataSize; 30 | uint32_t numBlocks; 31 | HFSPlusCmpfRsrcBlock blocks[0]; 32 | } __attribute__ ((packed)) HFSPlusCmpfRsrcBlockHead; 33 | 34 | typedef struct HFSPlusCmpfEnd { 35 | uint32_t pad[6]; 36 | uint16_t unk1; 37 | uint16_t unk2; 38 | uint16_t unk3; 39 | uint32_t magic; 40 | uint32_t flags; 41 | uint64_t size; 42 | uint32_t unk4; 43 | } __attribute__ ((packed)) HFSPlusCmpfEnd; 44 | 45 | typedef struct HFSPlusCompressed { 46 | Volume* volume; 47 | HFSPlusCatalogFile* file; 48 | io_func* io; 49 | size_t decmpfsSize; 50 | HFSPlusDecmpfs* decmpfs; 51 | 52 | HFSPlusCmpfRsrcHead rsrcHead; 53 | HFSPlusCmpfRsrcBlockHead* blocks; 54 | 55 | int dirty; 56 | 57 | uint8_t* cached; 58 | uint32_t cachedStart; 59 | uint32_t cachedEnd; 60 | } HFSPlusCompressed; 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | void flipHFSPlusDecmpfs(HFSPlusDecmpfs* compressData); 66 | io_func* openHFSPlusCompressed(Volume* volume, HFSPlusCatalogFile* file); 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/xpwn/include/hfs/hfslib.h: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "hfsplus.h" 3 | #include "abstractfile.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | void writeToFile(HFSPlusCatalogFile* file, AbstractFile* output, Volume* volume); 9 | void writeToHFSFile(HFSPlusCatalogFile* file, AbstractFile* input, Volume* volume); 10 | void get_hfs(Volume* volume, const char* inFileName, AbstractFile* output); 11 | int add_hfs(Volume* volume, AbstractFile* inFile, const char* outFileName); 12 | void grow_hfs(Volume* volume, uint64_t newSize); 13 | void removeAllInFolder(HFSCatalogNodeID folderID, Volume* volume, const char* parentName); 14 | void addAllInFolder(HFSCatalogNodeID folderID, Volume* volume, const char* parentName); 15 | void addall_hfs(Volume* volume, const char* dirToMerge, const char* dest); 16 | void extractAllInFolder(HFSCatalogNodeID folderID, Volume* volume); 17 | int copyAcrossVolumes(Volume* volume1, Volume* volume2, char* path1, char* path2); 18 | 19 | void hfs_untar(Volume* volume, AbstractFile* tarFile); 20 | void hfs_ls(Volume* volume, const char* path); 21 | void hfs_list(Volume* volume, const char* path, int recursive); 22 | void hfs_setsilence(int s); 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/xpwn/include/partial/firmwaremaster.h: -------------------------------------------------------------------------------- 1 | const char* FirmwareGetHardwareID(const char* platform); 2 | char* FirmwareGetURL(const char* platform, const char* version); 3 | 4 | -------------------------------------------------------------------------------- /src/xpwn/include/partial/partial.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct EndOfCD { 5 | uint32_t signature; 6 | uint16_t diskNo; 7 | uint16_t CDDiskNo; 8 | uint16_t CDDiskEntries; 9 | uint16_t CDEntries; 10 | uint32_t CDSize; 11 | uint32_t CDOffset; 12 | uint16_t lenComment; 13 | } __attribute__ ((packed)) EndOfCD; 14 | 15 | typedef struct CDFile { 16 | uint32_t signature; 17 | uint16_t version; 18 | uint16_t versionExtract; 19 | uint16_t flags; 20 | uint16_t method; 21 | uint16_t modTime; 22 | uint16_t modDate; 23 | uint32_t crc32; 24 | uint32_t compressedSize; 25 | uint32_t size; 26 | uint16_t lenFileName; 27 | uint16_t lenExtra; 28 | uint16_t lenComment; 29 | uint16_t diskStart; 30 | uint16_t internalAttr; 31 | uint32_t externalAttr; 32 | uint32_t offset; 33 | } __attribute__ ((packed)) CDFile; 34 | 35 | typedef struct LocalFile { 36 | uint32_t signature; 37 | uint16_t versionExtract; 38 | uint16_t flags; 39 | uint16_t method; 40 | uint16_t modTime; 41 | uint16_t modDate; 42 | uint32_t crc32; 43 | uint32_t compressedSize; 44 | uint32_t size; 45 | uint16_t lenFileName; 46 | uint16_t lenExtra; 47 | } __attribute__ ((packed)) LocalFile; 48 | 49 | typedef struct ZipInfo ZipInfo; 50 | 51 | typedef void (*PartialZipProgressCallback)(ZipInfo* info, CDFile* file, size_t progress); 52 | 53 | struct ZipInfo { 54 | char* url; 55 | uint64_t length; 56 | CURL* hIPSW; 57 | char* centralDirectory; 58 | size_t centralDirectoryRecvd; 59 | EndOfCD* centralDirectoryDesc; 60 | char centralDirectoryEnd[0xffff + sizeof(EndOfCD)]; 61 | size_t centralDirectoryEndRecvd; 62 | PartialZipProgressCallback progressCallback; 63 | }; 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | 69 | ZipInfo* PartialZipInit(const char* url); 70 | 71 | CDFile* PartialZipFindFile(ZipInfo* info, const char* fileName); 72 | 73 | CDFile* PartialZipListFiles(ZipInfo* info); 74 | 75 | unsigned char* PartialZipGetFile(ZipInfo* info, CDFile* file); 76 | 77 | void PartialZipRelease(ZipInfo* info); 78 | 79 | void PartialZipSetProgressCallback(ZipInfo* info, PartialZipProgressCallback progressCallback); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | -------------------------------------------------------------------------------- /src/xpwn/include/pref.h: -------------------------------------------------------------------------------- 1 | unsigned char _prefData[] = { 2 | 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x5f, 3 | 0x10, 0x1a, 0x53, 0x42, 0x53, 0x68, 0x6f, 0x77, 0x4e, 0x6f, 0x6e, 0x44, 4 | 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 5 | 0x41, 0x70, 0x70, 0x73, 0x09, 0x08, 0x0b, 0x28, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x29 9 | }; 10 | unsigned int _prefDataLen = 76; 11 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/8900.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef INC_8900_H 6 | #define INC_8900_H 7 | 8 | typedef struct { 9 | uint32_t magic; /* string "8900" */ 10 | unsigned char version[3]; /* string "1.0" */ 11 | uint8_t format; /* plaintext format is 0x4, encrypted format is 0x3 */ 12 | uint32_t unknown1; 13 | uint32_t sizeOfData; /* size of data (ie, filesize - header(0x800) - footer signature(0x80) - footer certificate(0xC0A)) */ 14 | uint32_t footerSignatureOffset; /* offset to footer signature */ 15 | uint32_t footerCertOffset; /* offset to footer certificate, from end of header (0x800) */ 16 | uint32_t footerCertLen; 17 | unsigned char salt[0x20]; /* a seemingly random salt (an awfully big one though... needs more attention) */ 18 | uint16_t unknown2; 19 | uint16_t epoch; /* the security epoch of the file */ 20 | unsigned char headerSignature[0x10]; /* encrypt(sha1(header[0:0x40])[0:0x10], key_0x837, zero_iv) */ 21 | unsigned char padding[0x7B0]; 22 | } __attribute__((__packed__)) Apple8900Header; 23 | 24 | #define SIGNATURE_8900 0x38393030 25 | 26 | #define key_0x837 ((uint8_t[]){0x18, 0x84, 0x58, 0xA6, 0xD1, 0x50, 0x34, 0xDF, 0xE3, 0x86, 0xF2, 0x3B, 0x61, 0xD4, 0x37, 0x74}) 27 | 28 | typedef struct Info8900 { 29 | AbstractFile* file; 30 | 31 | Apple8900Header header; 32 | size_t offset; 33 | void* buffer; 34 | 35 | unsigned char footerSignature[0x80]; 36 | unsigned char* footerCertificate; 37 | 38 | AES_KEY encryptKey; 39 | AES_KEY decryptKey; 40 | 41 | char dirty; 42 | char exploit; 43 | } Info8900; 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | AbstractFile* createAbstractFileFrom8900(AbstractFile* file); 49 | AbstractFile* duplicate8900File(AbstractFile* file, AbstractFile* backing); 50 | void replaceCertificate8900(AbstractFile* file, AbstractFile* certificate); 51 | void exploit8900(AbstractFile* file); 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/ibootim.h: -------------------------------------------------------------------------------- 1 | #ifndef IBOOTIM_H 2 | #define IBOOTIM_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct IBootIMHeader { 8 | char signature[8]; 9 | uint32_t unknown; 10 | uint32_t compression_type; 11 | uint32_t format; 12 | uint16_t width; 13 | uint16_t height; 14 | uint8_t padding[0x28]; 15 | } __attribute__((__packed__)) IBootIMHeader; 16 | 17 | #define IBOOTIM_SIG_UINT 0x69426F6F 18 | #define IBOOTIM_SIGNATURE "iBootIm" 19 | #define IBOOTIM_LZSS_TYPE 0x6C7A7373 20 | #define IBOOTIM_ARGB 0x61726762 21 | #define IBOOTIM_GREY 0x67726579 22 | 23 | typedef struct InfoIBootIM { 24 | AbstractFile* file; 25 | 26 | IBootIMHeader header; 27 | size_t length; 28 | size_t compLength; 29 | size_t offset; 30 | void* buffer; 31 | 32 | char dirty; 33 | } InfoIBootIM; 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | AbstractFile* createAbstractFileFromIBootIM(AbstractFile* file); 39 | AbstractFile* duplicateIBootIMFile(AbstractFile* file, AbstractFile* backing); 40 | void* replaceBootImage(AbstractFile* imageWrapper, const unsigned int* key, const unsigned int* iv, AbstractFile* png, size_t *fileSize); 41 | int convertToPNG(AbstractFile* imageWrapper, const unsigned int* key, const unsigned int* iv, const char* png); 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/img2.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IMG2_SIGNATURE 0x496D6732 5 | 6 | typedef struct Img2Header { 7 | uint32_t signature; /* 0x0 */ 8 | uint32_t imageType; /* 0x4 */ 9 | uint16_t unknown1; /* 0x8 */ 10 | uint16_t security_epoch; /* 0xa */ 11 | uint32_t flags1; /* 0xc */ 12 | uint32_t dataLenPadded; /* 0x10 */ 13 | uint32_t dataLen; /* 0x14 */ 14 | uint32_t unknown3; /* 0x18 */ 15 | uint32_t flags2; /* 0x1c */ /* 0x01000000 has to be unset */ 16 | uint8_t reserved[0x40]; /* 0x20 */ 17 | uint32_t unknown4; /* 0x60 */ /* some sort of length field? */ 18 | uint32_t header_checksum; /* 0x64 */ /* standard crc32 on first 0x64 bytes */ 19 | uint32_t checksum2; /* 0x68 */ 20 | uint8_t unknown5[0x394]; /* 0x68 */ 21 | } __attribute__((__packed__)) Img2Header; 22 | 23 | typedef struct InfoImg2 { 24 | AbstractFile* file; 25 | 26 | Img2Header header; 27 | size_t offset; 28 | void* buffer; 29 | 30 | char dirty; 31 | } InfoImg2; 32 | 33 | AbstractFile* createAbstractFileFromImg2(AbstractFile* file); 34 | AbstractFile* duplicateImg2File(AbstractFile* file, AbstractFile* backing); 35 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/img3.h: -------------------------------------------------------------------------------- 1 | #ifndef IMG3_H 2 | #define IMG3_H 3 | 4 | #include 5 | #include "common.h" 6 | #include 7 | #include 8 | 9 | #define IMG3_MAGIC 0x496d6733 10 | #define IMG3_DATA_MAGIC 0x44415441 11 | #define IMG3_VERS_MAGIC 0x56455253 12 | #define IMG3_SEPO_MAGIC 0x5345504f 13 | #define IMG3_SCEP_MAGIC 0x53434550 14 | #define IMG3_BORD_MAGIC 0x424f5244 15 | #define IMG3_BDID_MAGIC 0x42444944 16 | #define IMG3_SHSH_MAGIC 0x53485348 17 | #define IMG3_CERT_MAGIC 0x43455254 18 | #define IMG3_KBAG_MAGIC 0x4B424147 19 | #define IMG3_TYPE_MAGIC 0x54595045 20 | #define IMG3_ECID_MAGIC 0x45434944 21 | 22 | #define IMG3_SIGNATURE IMG3_MAGIC 23 | 24 | typedef struct Img3Element Img3Element; 25 | typedef struct Img3Info Img3Info; 26 | 27 | typedef void (*WriteImg3)(AbstractFile* file, Img3Element* element, Img3Info* info); 28 | typedef void (*FreeImg3)(Img3Element* element); 29 | 30 | typedef struct AppleImg3Header { 31 | uint32_t magic; 32 | uint32_t size; 33 | uint32_t dataSize; 34 | }__attribute__((__packed__)) AppleImg3Header; 35 | 36 | typedef struct AppleImg3RootExtra { 37 | uint32_t shshOffset; 38 | uint32_t name; 39 | }__attribute__((__packed__)) AppleImg3RootExtra; 40 | 41 | typedef struct AppleImg3RootHeader { 42 | AppleImg3Header base; 43 | AppleImg3RootExtra extra; 44 | }__attribute__((__packed__)) AppleImg3RootHeader; 45 | 46 | typedef struct AppleImg3KBAGHeader { 47 | 48 | uint32_t key_modifier; // key modifier, can be 0 or 1 49 | uint32_t key_bits; // number of bits in the key, can be 128, 192 or 256 (it seems only 128 is supported in current iBoot) 50 | } AppleImg3KBAGHeader; 51 | 52 | struct Img3Element 53 | { 54 | AppleImg3Header* header; 55 | WriteImg3 write; 56 | FreeImg3 free; 57 | void* data; 58 | struct Img3Element* next; 59 | }; 60 | 61 | struct Img3Info { 62 | AbstractFile* file; 63 | Img3Element* root; 64 | Img3Element* data; 65 | Img3Element* cert; 66 | Img3Element* kbag; 67 | Img3Element* type; 68 | int encrypted; 69 | AES_KEY encryptKey; 70 | AES_KEY decryptKey; 71 | uint8_t iv[16]; 72 | size_t offset; 73 | uint32_t replaceDWord; 74 | char dirty; 75 | char exploit24k; 76 | char exploitN8824k; 77 | char decryptLast; 78 | }; 79 | 80 | #ifdef __cplusplus 81 | extern "C" { 82 | #endif 83 | AbstractFile* createAbstractFileFromImg3(AbstractFile* file); 84 | AbstractFile* duplicateImg3File(AbstractFile* file, AbstractFile* backing); 85 | void replaceCertificateImg3(AbstractFile* file, AbstractFile* certificate); 86 | void exploit24kpwn(AbstractFile* file); 87 | void exploitN8824kpwn(AbstractFile* file); 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | 93 | #endif 94 | 95 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/libxpwn.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBXPWN_H 2 | #define LIBXPWN_H 3 | 4 | typedef void (*LogMessageCallback) (const char * Message); 5 | 6 | extern LogMessageCallback logCallback; 7 | 8 | #if __STDC_VERSION__ < 199901L 9 | # if __GNUC__ >= 2 10 | # define __func__ __FUNCTION__ 11 | # else 12 | # define __func__ "" 13 | # endif 14 | #endif 15 | 16 | #define XLOG(level, format, ...) Log(level, __FILE__, __LINE__, __func__, format, ## __VA_ARGS__) 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | void init_libxpwn(int *argc, char *argv[]); 22 | void libxpwn_log(LogMessageCallback callback); 23 | void libxpwn_loglevel(int logLevel); 24 | void Log(int level, const char* file, unsigned int line, const char* function, const char* format, ...); 25 | void TestByteOrder(); 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | extern int Img3DecryptLast; /* FALSE for <= 7a341, TRUE for >= 7c144 */ 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/lzss.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint32_t lzadler32(uint8_t *buf, int32_t len); 4 | int decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen); 5 | uint8_t *compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen); 6 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/lzssfile.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define COMP_SIGNATURE 0x636F6D70 5 | #define LZSS_SIGNATURE 0x6C7A7373 6 | 7 | typedef struct CompHeader { 8 | uint32_t signature; 9 | uint32_t compression_type; 10 | uint32_t checksum; 11 | uint32_t length_uncompressed; 12 | uint32_t length_compressed; 13 | uint8_t padding[0x16C]; 14 | } __attribute__((__packed__)) CompHeader; 15 | 16 | typedef struct InfoComp { 17 | AbstractFile* file; 18 | 19 | CompHeader header; 20 | size_t offset; 21 | void* buffer; 22 | 23 | char dirty; 24 | } InfoComp; 25 | 26 | AbstractFile* createAbstractFileFromComp(AbstractFile* file); 27 | AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing); 28 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/nor_files.h: -------------------------------------------------------------------------------- 1 | #ifndef NOR_FILES_H 2 | #define NOR_FILES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | AbstractFile* openAbstractFile(AbstractFile* file); 13 | AbstractFile* openAbstractFile2(AbstractFile* file, const unsigned int* key, const unsigned int* iv); 14 | AbstractFile* openAbstractFile3(AbstractFile* file, const unsigned int* key, const unsigned int* iv, int layers); 15 | AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing); 16 | AbstractFile* duplicateAbstractFile2(AbstractFile* file, AbstractFile* backing, const unsigned int* key, const unsigned int* iv, AbstractFile* certificate); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/outputstate.h: -------------------------------------------------------------------------------- 1 | #ifndef OUTPUTSTATE_H 2 | #define OUTPUTSTATE_H 3 | 4 | #include 5 | 6 | typedef struct OutputState { 7 | char* fileName; 8 | void* buffer; 9 | size_t bufferSize; 10 | char* tmpFileName; 11 | struct OutputState* next; 12 | struct OutputState* prev; 13 | } OutputState; 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | char* createTempFile(); 19 | void addToOutput2(OutputState** state, const char* fileName, void* buffer, const size_t bufferSize, char* tmpFileName); 20 | void addToOutput(OutputState** state, const char* fileName, void* buffer, const size_t bufferSize); 21 | void removeFileFromOutputState(OutputState** state, const char* fileName, int exact); 22 | AbstractFile* getFileFromOutputState(OutputState** state, const char* fileName); 23 | AbstractFile* getFileFromOutputStateForOverwrite(OutputState** state, const char* fileName); 24 | AbstractFile* getFileFromOutputStateForReplace(OutputState** state, const char* fileName); 25 | void writeOutput(OutputState** state, char* ipsw); 26 | void releaseOutput(OutputState** state); 27 | OutputState* loadZip2(const char* ipsw, int useMemory); 28 | void loadZipFile2(const char* ipsw, OutputState** output, const char* file, int useMemory); 29 | OutputState* loadZip(const char* ipsw); 30 | void loadZipFile(const char* ipsw, OutputState** output, const char* file); 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/plist.h: -------------------------------------------------------------------------------- 1 | #ifndef PLIST_H 2 | #define PLIST_H 3 | 4 | enum DictTypes { 5 | DictionaryType = 1, 6 | ArrayType, 7 | StringType, 8 | DataType, 9 | IntegerType, 10 | BoolType 11 | }; 12 | 13 | typedef struct DictValue { 14 | int type; 15 | char* key; 16 | struct DictValue* next; 17 | struct DictValue* prev; 18 | } DictValue; 19 | 20 | typedef struct StringValue { 21 | DictValue dValue; 22 | char* value; 23 | } StringValue; 24 | 25 | typedef struct DataValue { 26 | DictValue dValue; 27 | int len; 28 | unsigned char* value; 29 | } DataValue; 30 | 31 | typedef struct IntegerValue { 32 | DictValue dValue; 33 | int value; 34 | } IntegerValue; 35 | 36 | typedef struct BoolValue { 37 | DictValue dValue; 38 | char value; 39 | } BoolValue; 40 | 41 | typedef struct ArrayValue { 42 | DictValue dValue; 43 | int size; 44 | DictValue** values; 45 | } ArrayValue; 46 | 47 | typedef struct Dictionary { 48 | DictValue dValue; 49 | DictValue* values; 50 | } Dictionary; 51 | 52 | typedef struct Tag { 53 | char* name; 54 | char* xml; 55 | } Tag; 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | void createArray(ArrayValue* myself, char* xml); 61 | void createDictionary(Dictionary* myself, char* xml); 62 | void releaseArray(ArrayValue* myself); 63 | void releaseDictionary(Dictionary* myself); 64 | char* getXmlFromArrayValue(ArrayValue* myself, int tabsCount); 65 | char* getXmlFromDictionary(Dictionary* myself, int tabsCount); 66 | Dictionary* createRoot(char* xml); 67 | char* getXmlFromRoot(Dictionary* root); 68 | DictValue* getValueByKey(Dictionary* myself, const char* key); 69 | void addStringToArray(ArrayValue* array, char* str); 70 | void removeKey(Dictionary* dict, char* key); 71 | void addBoolToDictionary(Dictionary* dict, const char* key, int value); 72 | void addIntegerToDictionary(Dictionary* dict, const char* key, int value); 73 | void addValueToDictionary(Dictionary* dict, const char* key, DictValue* value); 74 | void unlinkValueFromDictionary(Dictionary* myself, DictValue *value); 75 | void prependToArray(ArrayValue* array, DictValue* curValue); 76 | void releaseArrayEx(ArrayValue* myself, int k); 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif 82 | 83 | -------------------------------------------------------------------------------- /src/xpwn/include/xpwn/pwnutil.h: -------------------------------------------------------------------------------- 1 | #ifndef PWNUTIL_H 2 | #define PWNUTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef int (*PatchFunction)(AbstractFile* file); 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch); 14 | Dictionary* parseIPSW(const char* inputIPSW, const char* bundleRoot, char** bundlePath, OutputState** state); 15 | Dictionary* parseIPSW2(const char* inputIPSW, const char* bundleRoot, char** bundlePath, OutputState** state, int useMemory); 16 | int doPatch(StringValue* patchValue, StringValue* fileValue, const char* bundlePath, OutputState** state, unsigned int* key, unsigned int* iv, int useMemory, int isPlain); 17 | int doDecrypt(StringValue* decryptValue, StringValue* fileValue, const char* bundlePath, OutputState** state, unsigned int* key, unsigned int* iv, int useMemory); 18 | void doPatchInPlace(Volume* volume, const char* filePath, const char* patchPath); 19 | void doPatchInPlaceMemoryPatch(Volume* volume, const char* filePath, void** patch, size_t* patchSize); 20 | void fixupBootNeuterArgs(Volume* volume, char unlockBaseband, char selfDestruct, char use39, char use46); 21 | void createRestoreOptions(Volume* volume, const char *optionsPlist, int SystemPartitionSize, int UpdateBaseband); 22 | int mergeIdentities(Dictionary* manifest, AbstractFile *idFile); 23 | 24 | int patchSigCheck(AbstractFile* file); 25 | int patchKernel(AbstractFile* file); 26 | int patchDeviceTree(AbstractFile* file); 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/bspatch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "abstractfile.h" 6 | 7 | #define BUFFERSIZE (256 * 1024) 8 | 9 | static off_t offtin(unsigned char *buf) 10 | { 11 | off_t y; 12 | 13 | y = buf[7] & 0x7F; 14 | y <<= 8; y += buf[6]; 15 | y <<= 8; y += buf[5]; 16 | y <<= 8; y += buf[4]; 17 | y <<= 8; y += buf[3]; 18 | y <<= 8; y += buf[2]; 19 | y <<= 8; y += buf[1]; 20 | y <<= 8; y += buf[0]; 21 | 22 | if(buf[7] & 0x80) y = -y; 23 | 24 | return y; 25 | } 26 | 27 | typedef struct { 28 | bz_stream bz2; 29 | AbstractFile* file; 30 | off_t offset; 31 | unsigned char* inBuffer; 32 | unsigned char* outBuffer; 33 | size_t bufferLen; 34 | char ended; 35 | } BZStream; 36 | 37 | size_t bzRead(int *bzerr, BZStream* stream, unsigned char* out, size_t len) { 38 | size_t toRead; 39 | size_t haveRead; 40 | size_t total; 41 | 42 | total = len; 43 | 44 | *bzerr = BZ_OK; 45 | 46 | while(total > 0) { 47 | if(!stream->ended) { 48 | memmove(stream->inBuffer, stream->bz2.next_in, stream->bz2.avail_in); 49 | stream->file->seek(stream->file, stream->offset); 50 | haveRead = stream->file->read(stream->file, stream->inBuffer + stream->bz2.avail_in, stream->bufferLen - stream->bz2.avail_in); 51 | stream->offset += haveRead; 52 | stream->bz2.avail_in += haveRead; 53 | stream->bz2.next_in = (char*) stream->inBuffer; 54 | 55 | *bzerr = BZ2_bzDecompress(&(stream->bz2)); 56 | 57 | if(*bzerr == BZ_STREAM_END) { 58 | stream->ended = TRUE; 59 | } else { 60 | if(*bzerr != BZ_OK) { 61 | return 0; 62 | } 63 | } 64 | } 65 | 66 | if(total > (stream->bufferLen - stream->bz2.avail_out)) { 67 | toRead = stream->bufferLen - stream->bz2.avail_out; 68 | } else { 69 | toRead = total; 70 | } 71 | 72 | memcpy(out, stream->outBuffer, toRead); 73 | memmove(stream->outBuffer, stream->outBuffer + toRead, stream->bufferLen - toRead); 74 | stream->bz2.next_out -= toRead; 75 | stream->bz2.avail_out += toRead; 76 | out += toRead; 77 | total -= toRead; 78 | 79 | if(total > 0 && stream->ended) { 80 | return (len - total); 81 | } 82 | } 83 | 84 | return len; 85 | } 86 | 87 | void closeBZStream(BZStream* stream) { 88 | free(stream->inBuffer); 89 | free(stream->outBuffer); 90 | BZ2_bzDecompressEnd(&(stream->bz2)); 91 | free(stream); 92 | } 93 | 94 | BZStream* openBZStream(AbstractFile* file, off_t offset, size_t bufferLen) { 95 | BZStream* stream; 96 | stream = (BZStream*) malloc(sizeof(BZStream)); 97 | stream->file = file; 98 | stream->offset = offset; 99 | stream->bufferLen = bufferLen; 100 | stream->inBuffer = (unsigned char*) malloc(bufferLen); 101 | stream->outBuffer = (unsigned char*) malloc(bufferLen); 102 | memset(&(stream->bz2), 0, sizeof(bz_stream)); 103 | BZ2_bzDecompressInit(&(stream->bz2), 0, FALSE); 104 | 105 | stream->bz2.next_in = (char*) stream->inBuffer; 106 | stream->bz2.avail_in = 0; 107 | stream->bz2.next_out = (char*) stream->outBuffer; 108 | stream->bz2.avail_out = bufferLen; 109 | 110 | stream->ended = FALSE; 111 | return stream; 112 | } 113 | 114 | int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch) { 115 | unsigned char header[32], buf[8]; 116 | off_t oldsize, newsize; 117 | off_t bzctrllen, bzdatalen; 118 | off_t oldpos, newpos; 119 | int i; 120 | int cbz2err, dbz2err, ebz2err; 121 | off_t ctrl[3]; 122 | size_t lenread; 123 | 124 | BZStream* cpfbz2; 125 | BZStream* dpfbz2; 126 | BZStream* epfbz2; 127 | 128 | /* Read header */ 129 | if (patch->read(patch, header, 32) < 32) { 130 | return -1; 131 | } 132 | 133 | /* Check for appropriate magic */ 134 | if (memcmp(header, "BSDIFF40", 8) != 0) 135 | return -2; 136 | 137 | /* Read lengths from header */ 138 | bzctrllen = offtin(header + 8); 139 | bzdatalen = offtin(header + 16); 140 | newsize = offtin(header + 24); 141 | 142 | if((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0)) 143 | return -3; 144 | 145 | cpfbz2 = openBZStream(patch, 32, 1024); 146 | dpfbz2 = openBZStream(patch, 32 + bzctrllen, 1024); 147 | epfbz2 = openBZStream(patch, 32 + bzctrllen + bzdatalen, 1024); 148 | 149 | oldsize = in->getLength(in); 150 | 151 | oldpos = 0; 152 | newpos = 0; 153 | unsigned char* writeBuffer = (unsigned char*) malloc(BUFFERSIZE); 154 | unsigned char* readBuffer = (unsigned char*) malloc(BUFFERSIZE); 155 | 156 | while(newpos < newsize) { 157 | /* Read control data */ 158 | for(i=0;i<=2;i++) { 159 | lenread = bzRead(&cbz2err, cpfbz2, buf, 8); 160 | if ((lenread < 8) || ((cbz2err != BZ_OK) && 161 | (cbz2err != BZ_STREAM_END))) 162 | return -4; 163 | ctrl[i] = offtin(buf); 164 | }; 165 | 166 | /* Sanity-check */ 167 | if((newpos + ctrl[0]) > newsize) 168 | return -5; 169 | 170 | /* Read diff string */ 171 | unsigned int toRead; 172 | unsigned int total = ctrl[0]; 173 | while(total > 0) { 174 | if(total > BUFFERSIZE) 175 | toRead = BUFFERSIZE; 176 | else 177 | toRead = total; 178 | 179 | memset(writeBuffer, 0, toRead); 180 | lenread = bzRead(&dbz2err, dpfbz2, writeBuffer, toRead); 181 | if ((lenread < toRead) || 182 | ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END))) 183 | return -6; 184 | 185 | /* Add old data to diff string */ 186 | in->seek(in, oldpos); 187 | unsigned int maxRead; 188 | if((oldpos + toRead) > oldsize) 189 | maxRead = (oldsize > oldpos) ? oldsize - oldpos : 0; 190 | else 191 | maxRead = toRead; 192 | 193 | in->read(in, readBuffer, maxRead); 194 | for(i = 0; i < maxRead; i++) { 195 | writeBuffer[i] += readBuffer[i]; 196 | } 197 | 198 | out->seek(out, newpos); 199 | out->write(out, writeBuffer, toRead); 200 | 201 | /* Adjust pointers */ 202 | newpos += toRead; 203 | oldpos += toRead; 204 | total -= toRead; 205 | } 206 | 207 | /* Sanity-check */ 208 | if((newpos + ctrl[1]) > newsize) 209 | return -7; 210 | 211 | total = ctrl[1]; 212 | 213 | while(total > 0){ 214 | if(total > BUFFERSIZE) 215 | toRead = BUFFERSIZE; 216 | else 217 | toRead = total; 218 | 219 | /* Read extra string */ 220 | lenread = bzRead(&ebz2err, epfbz2, writeBuffer, toRead); 221 | if ((lenread < toRead) || 222 | ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END))) 223 | return -8; 224 | 225 | out->seek(out, newpos); 226 | out->write(out, writeBuffer, toRead); 227 | 228 | /* Adjust pointers */ 229 | newpos += toRead; 230 | total -= toRead; 231 | } 232 | 233 | oldpos += ctrl[2]; 234 | }; 235 | 236 | free(writeBuffer); 237 | free(readBuffer); 238 | 239 | closeBZStream(cpfbz2); 240 | closeBZStream(dpfbz2); 241 | closeBZStream(epfbz2); 242 | 243 | out->close(out); 244 | in->close(in); 245 | 246 | patch->close(patch); 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/imagetool.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "abstractfile.h" 5 | #include 6 | #include 7 | #include 8 | 9 | void print_usage() { 10 | printf("usage:\timagetool extract [iv] [key]\n"); 11 | printf("usage:\timagetool inject [iv] [key]\n"); 12 | } 13 | 14 | int main(int argc, char* argv[]) { 15 | init_libxpwn(&argc, argv); 16 | 17 | if(argc < 4) { 18 | print_usage(); 19 | return 0; 20 | } 21 | 22 | AbstractFile* png; 23 | AbstractFile* img; 24 | AbstractFile* dst; 25 | void* imageBuffer; 26 | size_t imageSize; 27 | 28 | unsigned int key[32]; 29 | unsigned int iv[16]; 30 | unsigned int* pKey = NULL; 31 | unsigned int* pIV = NULL; 32 | 33 | if(strcmp(argv[1], "inject") == 0) { 34 | if(argc < 5) { 35 | print_usage(); 36 | return 0; 37 | } 38 | 39 | png = createAbstractFileFromFile(fopen(argv[2], "rb")); 40 | img = createAbstractFileFromFile(fopen(argv[4], "rb")); 41 | dst = createAbstractFileFromFile(fopen(argv[3], "wb")); 42 | 43 | if(argc >= 7) { 44 | sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 45 | &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8], 46 | &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]); 47 | 48 | sscanf(argv[6], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 49 | &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8], 50 | &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15], 51 | &key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24], 52 | &key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]); 53 | 54 | pKey = key; 55 | pIV = iv; 56 | } 57 | 58 | imageBuffer = replaceBootImage(img, pKey, pIV, png, &imageSize); 59 | dst->write(dst, imageBuffer, imageSize); 60 | dst->close(dst); 61 | } else if(strcmp(argv[1], "extract") == 0) { 62 | img = createAbstractFileFromFile(fopen(argv[2], "rb")); 63 | 64 | if(argc >= 6) { 65 | sscanf(argv[4], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 66 | &iv[0], &iv[1], &iv[2], &iv[3], &iv[4], &iv[5], &iv[6], &iv[7], &iv[8], 67 | &iv[9], &iv[10], &iv[11], &iv[12], &iv[13], &iv[14], &iv[15]); 68 | 69 | sscanf(argv[5], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 70 | &key[0], &key[1], &key[2], &key[3], &key[4], &key[5], &key[6], &key[7], &key[8], 71 | &key[9], &key[10], &key[11], &key[12], &key[13], &key[14], &key[15], 72 | &key[16], &key[17], &key[18], &key[19], &key[20], &key[21], &key[22], &key[23], &key[24], 73 | &key[25], &key[26], &key[27], &key[28], &key[29], &key[30], &key[31]); 74 | 75 | pKey = key; 76 | pIV = iv; 77 | } 78 | 79 | if(convertToPNG(img, pKey, pIV, argv[3]) < 0) { 80 | XLOG(1, "error converting img to png"); 81 | } 82 | } 83 | 84 | return 0; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/img2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "common.h" 6 | #include "abstractfile.h" 7 | #include 8 | 9 | void flipImg2Header(Img2Header* header) { 10 | FLIPENDIANLE(header->signature); 11 | FLIPENDIANLE(header->imageType); 12 | FLIPENDIANLE(header->unknown1); 13 | FLIPENDIANLE(header->security_epoch); 14 | FLIPENDIANLE(header->flags1); 15 | FLIPENDIANLE(header->dataLen); 16 | FLIPENDIANLE(header->dataLenPadded); 17 | FLIPENDIANLE(header->unknown3); 18 | FLIPENDIANLE(header->flags2); 19 | FLIPENDIANLE(header->unknown4); 20 | FLIPENDIANLE(header->header_checksum); 21 | FLIPENDIANLE(header->checksum2); 22 | } 23 | 24 | size_t readImg2(AbstractFile* file, void* data, size_t len) { 25 | InfoImg2* info = (InfoImg2*) (file->data); 26 | memcpy(data, (void*)((uint8_t*)info->buffer + (uint32_t)info->offset), len); 27 | info->offset += (size_t)len; 28 | return len; 29 | } 30 | 31 | size_t writeImg2(AbstractFile* file, const void* data, size_t len) { 32 | InfoImg2* info = (InfoImg2*) (file->data); 33 | 34 | while((info->offset + (size_t)len) > info->header.dataLen) { 35 | info->header.dataLen = info->offset + (size_t)len; 36 | info->buffer = realloc(info->buffer, info->header.dataLen); 37 | } 38 | 39 | memcpy((void*)((uint8_t*)info->buffer + (uint32_t)info->offset), data, len); 40 | info->offset += (size_t)len; 41 | 42 | info->dirty = TRUE; 43 | 44 | return len; 45 | } 46 | 47 | int seekImg2(AbstractFile* file, off_t offset) { 48 | InfoImg2* info = (InfoImg2*) (file->data); 49 | info->offset = (size_t)offset; 50 | return 0; 51 | } 52 | 53 | off_t tellImg2(AbstractFile* file) { 54 | InfoImg2* info = (InfoImg2*) (file->data); 55 | return (off_t)info->offset; 56 | } 57 | 58 | off_t getLengthImg2(AbstractFile* file) { 59 | InfoImg2* info = (InfoImg2*) (file->data); 60 | return info->header.dataLen; 61 | } 62 | 63 | void closeImg2(AbstractFile* file) { 64 | InfoImg2* info = (InfoImg2*) (file->data); 65 | uint32_t cksum; 66 | 67 | if(info->dirty) { 68 | info->file->seek(info->file, sizeof(info->header)); 69 | info->file->write(info->file, info->buffer, info->header.dataLen); 70 | info->header.dataLenPadded = info->header.dataLen; 71 | 72 | flipImg2Header(&(info->header)); 73 | 74 | cksum = crc32(0, (unsigned char *)&(info->header), 0x64); 75 | FLIPENDIANLE(cksum); 76 | info->header.header_checksum = cksum; 77 | 78 | info->file->seek(info->file, 0); 79 | info->file->write(info->file, &(info->header), sizeof(info->header)); 80 | } 81 | 82 | free(info->buffer); 83 | info->file->close(info->file); 84 | free(info); 85 | free(file); 86 | } 87 | 88 | 89 | AbstractFile* createAbstractFileFromImg2(AbstractFile* file) { 90 | InfoImg2* info; 91 | AbstractFile* toReturn; 92 | 93 | if(!file) { 94 | return NULL; 95 | } 96 | 97 | info = (InfoImg2*) malloc(sizeof(InfoImg2)); 98 | info->file = file; 99 | file->seek(file, 0); 100 | file->read(file, &(info->header), sizeof(info->header)); 101 | flipImg2Header(&(info->header)); 102 | if(info->header.signature != IMG2_SIGNATURE) { 103 | free(info); 104 | return NULL; 105 | } 106 | 107 | info->buffer = malloc(info->header.dataLen); 108 | file->read(file, info->buffer, info->header.dataLen); 109 | 110 | info->dirty = FALSE; 111 | 112 | info->offset = 0; 113 | 114 | toReturn = (AbstractFile*) malloc(sizeof(AbstractFile)); 115 | toReturn->data = info; 116 | toReturn->read = readImg2; 117 | toReturn->write = writeImg2; 118 | toReturn->seek = seekImg2; 119 | toReturn->tell = tellImg2; 120 | toReturn->getLength = getLengthImg2; 121 | toReturn->close = closeImg2; 122 | toReturn->type = AbstractFileTypeImg2; 123 | return toReturn; 124 | } 125 | 126 | AbstractFile* duplicateImg2File(AbstractFile* file, AbstractFile* backing) { 127 | InfoImg2* info; 128 | AbstractFile* toReturn; 129 | 130 | if(!file) { 131 | return NULL; 132 | } 133 | 134 | info = (InfoImg2*) malloc(sizeof(InfoImg2)); 135 | memcpy(info, file->data, sizeof(InfoImg2)); 136 | 137 | info->file = backing; 138 | info->buffer = malloc(1); 139 | info->header.dataLen = 0; 140 | info->dirty = TRUE; 141 | info->offset = 0; 142 | 143 | toReturn = (AbstractFile*) malloc(sizeof(AbstractFile)); 144 | toReturn->data = info; 145 | toReturn->read = readImg2; 146 | toReturn->write = writeImg2; 147 | toReturn->seek = seekImg2; 148 | toReturn->tell = tellImg2; 149 | toReturn->getLength = getLengthImg2; 150 | toReturn->close = closeImg2; 151 | toReturn->type = AbstractFileTypeImg2; 152 | return toReturn; 153 | } 154 | 155 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/itunespwn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define SHGFP_TYPE_CURRENT 0 11 | 12 | const char restorePlist[] = "\n\n\n\n DeviceClass\n iPhone\n DeviceMap\n \n FirmwareDirectory\n Firmware\n ProductBuildVersion\n 5A348\n ProductType\n iPhone1,1\n ProductVersion\n 2.0\n SupportedProductTypeIDs\n \n DFU\n \n 304218112\n \n Recovery\n \n \n\n\n"; 13 | 14 | 15 | int main(int argc, char* argv[]) { 16 | if(argc < 2) { 17 | printf("usage: %s \n", argv[0]); 18 | return 0; 19 | } 20 | 21 | char path[MAX_PATH]; 22 | SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path); 23 | strcat(path, "\\Apple Computer\\iTunes\\Device Support"); 24 | 25 | struct stat st; 26 | if(stat(path, &st) < 0) { 27 | mkdir(path, 0755); 28 | } 29 | 30 | strcat(path, "\\x12220000_4_Recovery.ipsw"); 31 | 32 | void* buffer; 33 | buffer = malloc(sizeof(restorePlist) - 1); 34 | memcpy(buffer, restorePlist, sizeof(restorePlist) - 1); 35 | 36 | OutputState* data = NULL; 37 | loadZipFile(argv[1], &data, "Firmware/dfu/WTF.s5l8900xall.RELEASE.dfu"); 38 | addToOutput(&data, "Restore.plist", buffer, sizeof(restorePlist) - 1); 39 | writeOutput(&data, path); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/libxpwn.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | 6 | LogMessageCallback logCallback; 7 | char endianness; 8 | int GlobalLogLevel; 9 | 10 | int Img3DecryptLast = TRUE; /* FALSE for <= 7a341, TRUE for >= 7c144 */ 11 | 12 | void TestByteOrder() 13 | { 14 | short int word = 0x0001; 15 | char *byte = (char *) &word; 16 | endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN; 17 | } 18 | 19 | void defaultCallback(const char* Message) { 20 | printf("%s", Message); 21 | } 22 | 23 | void init_libxpwn(int *argc, char *argv[]) { 24 | int i, j, n = *argc; 25 | for (i = 0; i < n; i++) { 26 | if (!strcmp(argv[i], "--old-img3-decrypt")) { 27 | n--; 28 | memmove(&argv[i], &argv[i + 1], (n - i) * sizeof(char *)); 29 | Img3DecryptLast = FALSE; 30 | } 31 | } 32 | argv[*argc = n] = NULL; 33 | 34 | TestByteOrder(); 35 | GlobalLogLevel = 0xFF; 36 | logCallback = defaultCallback; 37 | } 38 | 39 | void libxpwn_log(LogMessageCallback callback) { 40 | logCallback = callback; 41 | } 42 | 43 | void libxpwn_loglevel(int logLevel) { 44 | GlobalLogLevel = logLevel; 45 | } 46 | 47 | void Log(int level, const char* file, unsigned int line, const char* function, const char* format, ...) { 48 | #ifdef HARD_LOG 49 | static FILE* logFile = NULL; 50 | if(logFile == NULL) 51 | logFile = fopen("log.txt", "w"); 52 | #endif 53 | 54 | char mainBuffer[1024]; 55 | char buffer[1024]; 56 | 57 | if(level >= GlobalLogLevel) { 58 | return; 59 | } 60 | 61 | va_list args; 62 | va_start(args, format); 63 | vsnprintf(buffer, sizeof(buffer), format, args); 64 | va_end(args); 65 | 66 | switch(level) { 67 | case 0: 68 | case 1: 69 | strcpy(mainBuffer, buffer); 70 | break; 71 | default: 72 | snprintf(mainBuffer, sizeof(mainBuffer), "%s:%s:%d: %s", file, function, line, buffer); 73 | } 74 | logCallback(mainBuffer); 75 | 76 | #ifdef HARD_LOG 77 | strcat(mainBuffer, "\n"); 78 | fwrite(mainBuffer, 1, strlen(mainBuffer), logFile); 79 | fflush(logFile); 80 | #endif 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/lzssfile.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "common.h" 4 | #include "abstractfile.h" 5 | #include 6 | #include 7 | #include 8 | 9 | void flipCompHeader(CompHeader* header) { 10 | FLIPENDIAN(header->signature); 11 | FLIPENDIAN(header->compression_type); 12 | FLIPENDIAN(header->checksum); 13 | FLIPENDIAN(header->length_uncompressed); 14 | FLIPENDIAN(header->length_compressed); 15 | } 16 | 17 | size_t readComp(AbstractFile* file, void* data, size_t len) { 18 | InfoComp* info = (InfoComp*) (file->data); 19 | memcpy(data, (void*)((uint8_t*)info->buffer + (uint32_t)info->offset), len); 20 | info->offset += (size_t)len; 21 | return len; 22 | } 23 | 24 | size_t writeComp(AbstractFile* file, const void* data, size_t len) { 25 | InfoComp* info = (InfoComp*) (file->data); 26 | 27 | while((info->offset + (size_t)len) > info->header.length_uncompressed) { 28 | info->header.length_uncompressed = info->offset + (size_t)len; 29 | info->buffer = realloc(info->buffer, info->header.length_uncompressed); 30 | } 31 | 32 | memcpy((void*)((uint8_t*)info->buffer + (uint32_t)info->offset), data, len); 33 | info->offset += (size_t)len; 34 | 35 | info->dirty = TRUE; 36 | 37 | return len; 38 | } 39 | 40 | int seekComp(AbstractFile* file, off_t offset) { 41 | InfoComp* info = (InfoComp*) (file->data); 42 | info->offset = (size_t)offset; 43 | return 0; 44 | } 45 | 46 | off_t tellComp(AbstractFile* file) { 47 | InfoComp* info = (InfoComp*) (file->data); 48 | return (off_t)info->offset; 49 | } 50 | 51 | off_t getLengthComp(AbstractFile* file) { 52 | InfoComp* info = (InfoComp*) (file->data); 53 | return info->header.length_uncompressed; 54 | } 55 | 56 | void closeComp(AbstractFile* file) { 57 | InfoComp* info = (InfoComp*) (file->data); 58 | uint8_t *compressed; 59 | if(info->dirty) { 60 | info->header.checksum = lzadler32((uint8_t*)info->buffer, info->header.length_uncompressed); 61 | 62 | compressed = malloc(info->header.length_uncompressed * 2); 63 | info->header.length_compressed = (uint32_t)(compress_lzss(compressed, info->header.length_uncompressed * 2, info->buffer, info->header.length_uncompressed) - compressed); 64 | 65 | info->file->seek(info->file, sizeof(info->header)); 66 | info->file->write(info->file, compressed, info->header.length_compressed); 67 | 68 | free(compressed); 69 | 70 | flipCompHeader(&(info->header)); 71 | info->file->seek(info->file, 0); 72 | info->file->write(info->file, &(info->header), sizeof(info->header)); 73 | } 74 | 75 | free(info->buffer); 76 | info->file->close(info->file); 77 | free(info); 78 | free(file); 79 | } 80 | 81 | 82 | AbstractFile* createAbstractFileFromComp(AbstractFile* file) { 83 | InfoComp* info; 84 | AbstractFile* toReturn; 85 | uint8_t *compressed; 86 | 87 | if(!file) { 88 | return NULL; 89 | } 90 | 91 | info = (InfoComp*) malloc(sizeof(InfoComp)); 92 | info->file = file; 93 | file->seek(file, 0); 94 | file->read(file, &(info->header), sizeof(info->header)); 95 | flipCompHeader(&(info->header)); 96 | if(info->header.signature != COMP_SIGNATURE) { 97 | free(info); 98 | return NULL; 99 | } 100 | 101 | if(info->header.compression_type != LZSS_SIGNATURE) { 102 | free(info); 103 | return NULL; 104 | } 105 | 106 | info->buffer = malloc(info->header.length_uncompressed); 107 | compressed = malloc(info->header.length_compressed); 108 | file->read(file, compressed, info->header.length_compressed); 109 | 110 | uint32_t real_uncompressed = decompress_lzss(info->buffer, compressed, info->header.length_compressed); 111 | if(real_uncompressed != info->header.length_uncompressed) { 112 | XLOG(5, "mismatch: %d %d %d %x %x\n", info->header.length_compressed, real_uncompressed, info->header.length_uncompressed, compressed[info->header.length_compressed - 2], compressed[info->header.length_compressed - 1]); 113 | free(compressed); 114 | free(info); 115 | return NULL; 116 | } 117 | 118 | XLOG(5, "match: %d %d %d %x %x\n", info->header.length_compressed, real_uncompressed, info->header.length_uncompressed, compressed[info->header.length_compressed - 2], compressed[info->header.length_compressed - 1]); 119 | 120 | free(compressed); 121 | 122 | info->dirty = FALSE; 123 | 124 | info->offset = 0; 125 | 126 | toReturn = (AbstractFile*) malloc(sizeof(AbstractFile)); 127 | toReturn->data = info; 128 | toReturn->read = readComp; 129 | toReturn->write = writeComp; 130 | toReturn->seek = seekComp; 131 | toReturn->tell = tellComp; 132 | toReturn->getLength = getLengthComp; 133 | toReturn->close = closeComp; 134 | toReturn->type = AbstractFileTypeLZSS; 135 | 136 | return toReturn; 137 | } 138 | 139 | AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing) { 140 | InfoComp* info; 141 | AbstractFile* toReturn; 142 | 143 | if(!file) { 144 | return NULL; 145 | } 146 | 147 | info = (InfoComp*) malloc(sizeof(InfoComp)); 148 | memcpy(info, file->data, sizeof(InfoComp)); 149 | 150 | info->file = backing; 151 | info->buffer = malloc(1); 152 | info->header.length_uncompressed = 0; 153 | info->dirty = TRUE; 154 | info->offset = 0; 155 | 156 | toReturn = (AbstractFile*) malloc(sizeof(AbstractFile)); 157 | toReturn->data = info; 158 | toReturn->read = readComp; 159 | toReturn->write = writeComp; 160 | toReturn->seek = seekComp; 161 | toReturn->tell = tellComp; 162 | toReturn->getLength = getLengthComp; 163 | toReturn->close = closeComp; 164 | toReturn->type = AbstractFileTypeLZSS; 165 | 166 | return toReturn; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/nor_files.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | AbstractFile* openAbstractFile(AbstractFile* file) { 9 | uint32_t signatureBE; 10 | uint32_t signatureLE; 11 | 12 | if(!file) 13 | return NULL; 14 | 15 | file->seek(file, 0); 16 | file->read(file, &signatureBE, sizeof(signatureBE)); 17 | signatureLE = signatureBE; 18 | FLIPENDIAN(signatureBE); 19 | FLIPENDIANLE(signatureLE); 20 | file->seek(file, 0); 21 | 22 | if(signatureBE == SIGNATURE_8900) { 23 | return openAbstractFile(createAbstractFileFrom8900(file)); 24 | } else if(signatureLE == IMG2_SIGNATURE) { 25 | return openAbstractFile(createAbstractFileFromImg2(file)); 26 | } else if(signatureLE == IMG3_SIGNATURE) { 27 | return openAbstractFile(createAbstractFileFromImg3(file)); 28 | } else if(signatureBE == COMP_SIGNATURE) { 29 | return openAbstractFile(createAbstractFileFromComp(file)); 30 | } else if(signatureBE == IBOOTIM_SIG_UINT) { 31 | return openAbstractFile(createAbstractFileFromIBootIM(file)); 32 | } else { 33 | return file; 34 | } 35 | } 36 | 37 | AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing) { 38 | uint32_t signatureBE; 39 | uint32_t signatureLE; 40 | AbstractFile* orig; 41 | 42 | if (!backing) { /* imagine that: createAbstractFileFromComp() fails, because of decompress_lzss() */ 43 | return NULL; 44 | } 45 | 46 | file->seek(file, 0); 47 | file->read(file, &signatureBE, sizeof(signatureBE)); 48 | signatureLE = signatureBE; 49 | FLIPENDIAN(signatureBE); 50 | FLIPENDIANLE(signatureLE); 51 | file->seek(file, 0); 52 | 53 | if(signatureBE == SIGNATURE_8900) { 54 | orig = createAbstractFileFrom8900(file); 55 | return duplicateAbstractFile(orig, duplicate8900File(orig, backing)); 56 | } else if(signatureLE == IMG2_SIGNATURE) { 57 | orig = createAbstractFileFromImg2(file); 58 | return duplicateAbstractFile(orig, duplicateImg2File(orig, backing)); 59 | } else if(signatureLE == IMG3_SIGNATURE) { 60 | orig = createAbstractFileFromImg3(file); 61 | return duplicateAbstractFile(orig, duplicateImg3File(orig, backing)); 62 | } else if(signatureBE == COMP_SIGNATURE) { 63 | orig = createAbstractFileFromComp(file); 64 | return duplicateAbstractFile(orig, duplicateCompFile(orig, backing)); 65 | } else if(signatureBE == IBOOTIM_SIG_UINT) { 66 | orig = createAbstractFileFromIBootIM(file); 67 | return duplicateAbstractFile(orig, duplicateIBootIMFile(orig, backing)); 68 | } else { 69 | file->close(file); 70 | return backing; 71 | } 72 | } 73 | 74 | AbstractFile* openAbstractFile3(AbstractFile* file, const unsigned int* key, const unsigned int* iv, int layers) { 75 | uint32_t signatureBE; 76 | uint32_t signatureLE; 77 | 78 | if(!file) 79 | return NULL; 80 | 81 | file->seek(file, 0); 82 | file->read(file, &signatureBE, sizeof(signatureBE)); 83 | signatureLE = signatureBE; 84 | FLIPENDIAN(signatureBE); 85 | FLIPENDIANLE(signatureLE); 86 | file->seek(file, 0); 87 | 88 | AbstractFile* cur; 89 | if(signatureBE == SIGNATURE_8900) { 90 | cur = createAbstractFileFrom8900(file); 91 | } else if(signatureLE == IMG2_SIGNATURE) { 92 | cur = createAbstractFileFromImg2(file); 93 | } else if(signatureLE == IMG3_SIGNATURE) { 94 | AbstractFile2* img3 = (AbstractFile2*) createAbstractFileFromImg3(file); 95 | if(key && iv) 96 | img3->setKey(img3, key, iv); 97 | cur = (AbstractFile*) img3; 98 | key = NULL; 99 | iv = NULL; 100 | } else if(signatureBE == COMP_SIGNATURE) { 101 | cur = createAbstractFileFromComp(file); 102 | key = NULL; 103 | iv = NULL; 104 | } else if(signatureBE == IBOOTIM_SIG_UINT) { 105 | cur = createAbstractFileFromIBootIM(file); 106 | key = NULL; 107 | iv = NULL; 108 | } else { 109 | return file; 110 | } 111 | 112 | if(layers < 0 || layers > 0) 113 | return openAbstractFile3(cur, key, iv, layers - 1); 114 | else 115 | return cur; 116 | } 117 | 118 | AbstractFile* openAbstractFile2(AbstractFile* file, const unsigned int* key, const unsigned int* iv) { 119 | return openAbstractFile3(file, key, iv, -1); 120 | } 121 | 122 | AbstractFile* duplicateAbstractFile2(AbstractFile* file, AbstractFile* backing, const unsigned int* key, const unsigned int* iv, AbstractFile* certificate) { 123 | uint32_t signatureBE; 124 | uint32_t signatureLE; 125 | AbstractFile* orig; 126 | AbstractFile* newFile; 127 | 128 | file->seek(file, 0); 129 | file->read(file, &signatureBE, sizeof(signatureBE)); 130 | signatureLE = signatureBE; 131 | FLIPENDIAN(signatureBE); 132 | FLIPENDIANLE(signatureLE); 133 | file->seek(file, 0); 134 | 135 | if(signatureBE == SIGNATURE_8900) { 136 | orig = createAbstractFileFrom8900(file); 137 | newFile = duplicate8900File(orig, backing); 138 | if(certificate != NULL) 139 | replaceCertificate8900(newFile, certificate); 140 | return duplicateAbstractFile(orig, newFile); 141 | } else if(signatureLE == IMG2_SIGNATURE) { 142 | orig = createAbstractFileFromImg2(file); 143 | return duplicateAbstractFile(orig, duplicateImg2File(orig, backing)); 144 | } else if(signatureLE == IMG3_SIGNATURE) { 145 | AbstractFile2* img3 = (AbstractFile2*) createAbstractFileFromImg3(file); 146 | if(key != NULL) 147 | img3->setKey(img3, key, iv); 148 | 149 | AbstractFile2* newFile = (AbstractFile2*) duplicateImg3File((AbstractFile*) img3, backing); 150 | if(key != NULL) 151 | img3->setKey(newFile, key, iv); 152 | 153 | if(certificate != NULL) 154 | replaceCertificateImg3((AbstractFile*) newFile, certificate); 155 | return duplicateAbstractFile((AbstractFile*) img3, (AbstractFile*) newFile); 156 | } else if(signatureBE == COMP_SIGNATURE) { 157 | orig = createAbstractFileFromComp(file); 158 | return duplicateAbstractFile(orig, duplicateCompFile(orig, backing)); 159 | } else if(signatureBE == IBOOTIM_SIG_UINT) { 160 | orig = createAbstractFileFromIBootIM(file); 161 | return duplicateAbstractFile(orig, duplicateIBootIMFile(orig, backing)); 162 | } else { 163 | file->close(file); 164 | return backing; 165 | } 166 | } 167 | 168 | 169 | void replaceCertificateAbstractFile(AbstractFile* file, AbstractFile* certificate) { 170 | uint32_t signatureBE; 171 | uint32_t signatureLE; 172 | AbstractFile* f; 173 | 174 | file->seek(file, 0); 175 | file->read(file, &signatureBE, sizeof(signatureBE)); 176 | signatureLE = signatureBE; 177 | FLIPENDIAN(signatureBE); 178 | FLIPENDIANLE(signatureLE); 179 | file->seek(file, 0); 180 | 181 | if(signatureBE == SIGNATURE_8900) { 182 | f = createAbstractFileFrom8900(file); 183 | replaceCertificate8900(f, certificate); 184 | f->close(f); 185 | } else if(signatureLE == IMG3_SIGNATURE) { 186 | f = createAbstractFileFromImg3(file); 187 | replaceCertificateImg3(f, certificate); 188 | f->close(f); 189 | } 190 | } 191 | 192 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/ticket.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef WIN32 9 | #include 10 | #endif 11 | 12 | char endianness; 13 | 14 | extern uint64_t MaxLoadZipSize; 15 | void flipAppleImg3Header(AppleImg3Header* header); 16 | 17 | #pragma GCC diagnostic push 18 | #pragma GCC diagnostic ignored "-Wmultichar" 19 | const char *componentName(unsigned int magic) { 20 | switch (magic) { 21 | case 'illb': return "LLB"; 22 | case 'krnl': return "KernelCache"; 23 | case 'logo': return "AppleLogo"; 24 | case 'dtre': return "DeviceTree"; 25 | case 'ibot': return "iBoot"; 26 | case 'recm': return "RecoveryMode"; 27 | case 'bat0': return "BatteryLow0"; 28 | case 'bat1': return "BatteryLow1"; 29 | case 'batF': return "BatteryFull"; 30 | case 'chg0': return "BatteryCharging0"; 31 | case 'chg1': return "BatteryCharging1"; 32 | case 'glyC': return "BatteryCharging"; 33 | case 'glyP': return "BatteryPlugin"; 34 | default: 35 | XLOG(0, "unknown magic %08x\n", magic); 36 | exit(1); 37 | } 38 | } 39 | 40 | static DataValue * 41 | findPartialDigest(Dictionary *manifest, const char *component) { 42 | int i; 43 | ArrayValue *buildIdentities = (ArrayValue *)getValueByKey(manifest, "BuildIdentities"); 44 | if (!buildIdentities) { 45 | return NULL; 46 | } 47 | for (i = 0; i < buildIdentities->size; i++) { 48 | Dictionary *dict = (Dictionary *)buildIdentities->values[i]; 49 | if (!dict) continue; 50 | dict = (Dictionary *)getValueByKey(dict, "Manifest"); 51 | if (!dict) continue; 52 | for (dict = (Dictionary *)dict->values; dict; dict = (Dictionary*) dict->dValue.next) { 53 | if (!strcmp(dict->dValue.key, component)) { 54 | DataValue *partial = (DataValue *)getValueByKey(dict, "PartialDigest"); 55 | if (partial) { 56 | return partial; 57 | } 58 | } 59 | } 60 | } 61 | return NULL; 62 | } 63 | 64 | DataValue *makeData(const void *data, int size) { 65 | DataValue *val = malloc(sizeof(DataValue)); 66 | val->dValue.type = DataType; 67 | val->len = size; 68 | val->value = malloc(size); 69 | memcpy(val->value, data, size); 70 | return val; 71 | } 72 | 73 | DataValue *makeBlob(AppleImg3Header *ecid, AppleImg3Header *cert, const void *data, int size) { 74 | DataValue *val; 75 | AppleImg3Header shsh; 76 | int ecid_size = ecid->size; 77 | int cert_size = cert->size; 78 | int total = ecid_size + sizeof(AppleImg3Header) + size + cert_size; 79 | char *ptr = malloc(total); 80 | 81 | shsh.magic = 'SHSH'; 82 | shsh.size = size + 12; 83 | shsh.dataSize = size; 84 | flipAppleImg3Header(&shsh); 85 | flipAppleImg3Header(ecid); 86 | flipAppleImg3Header(cert); 87 | 88 | memcpy(ptr, ecid, ecid_size); 89 | memcpy(ptr + ecid_size, &shsh, sizeof(AppleImg3Header)); 90 | memcpy(ptr + ecid_size + sizeof(AppleImg3Header), data, size); 91 | memcpy(ptr + ecid_size + sizeof(AppleImg3Header) + size, cert, cert_size); 92 | 93 | flipAppleImg3Header(ecid); 94 | flipAppleImg3Header(cert); 95 | 96 | val = malloc(sizeof(DataValue)); 97 | val->dValue.type = DataType; 98 | val->len = total; 99 | val->value = malloc(total); 100 | memcpy(val->value, ptr, total); 101 | return val; 102 | } 103 | 104 | int main(int argc, char* argv[]) { 105 | init_libxpwn(&argc, argv); 106 | 107 | OutputState *outputState; 108 | size_t fileLength; 109 | 110 | AbstractFile *dumpFile; 111 | char *dumpData; 112 | Dictionary *signDict; 113 | DataValue *llb = NULL; 114 | AppleImg3Header *cert = NULL; 115 | AppleImg3Header *ecid = NULL; 116 | uint64_t thisecid = 0; 117 | 118 | AbstractFile *manifestFile; 119 | Dictionary* manifest; 120 | 121 | char *plist; 122 | int i; 123 | 124 | int fromzip = FALSE; 125 | 126 | if (argc < 4) { 127 | XLOG(0, "usage %s file.dump file.shsh BuildManifest.plist [-z]\n", argv[0]); 128 | return 0; 129 | } 130 | 131 | for (i = 4; i < argc; i++) { 132 | if (!strcmp(argv[i], "-z")) { 133 | fromzip = TRUE; 134 | continue; 135 | } 136 | } 137 | 138 | MaxLoadZipSize = 128 * 1024; 139 | if (fromzip) { 140 | outputState = loadZip2(argv[3], TRUE); // XXX ASSERT 141 | manifestFile = getFileFromOutputState(&outputState, "BuildManifest.plist"); 142 | } else { 143 | outputState = NULL; 144 | manifestFile = createAbstractFileFromFile(fopen(argv[3], "rb")); 145 | } 146 | if (!manifestFile) { 147 | XLOG(0, "FATAL: cannot open %s\n", argv[3]); 148 | exit(1); 149 | } 150 | 151 | fileLength = manifestFile->getLength(manifestFile); 152 | plist = malloc(fileLength); 153 | manifestFile->read(manifestFile, plist, fileLength); 154 | manifestFile->close(manifestFile); 155 | manifest = createRoot(plist); 156 | free(plist); 157 | 158 | if (!manifest) { 159 | XLOG(0, "FATAL: cannot parse %s\n", argv[3]); 160 | exit(1); 161 | } 162 | 163 | releaseOutput(&outputState); 164 | 165 | dumpFile = createAbstractFileFromFile(fopen(argv[1], "rb")); 166 | if (!dumpFile) { 167 | XLOG(0, "FATAL: cannot open %s\n", argv[1]); 168 | exit(1); 169 | } 170 | 171 | fileLength = dumpFile->getLength(dumpFile); 172 | dumpData = malloc(fileLength); 173 | dumpFile->read(dumpFile, dumpData, fileLength); 174 | dumpFile->close(dumpFile); 175 | 176 | signDict = createRoot(""); 177 | 178 | for (i = 0; i < fileLength - 8; ) { 179 | unsigned magic = *(unsigned *)(dumpData + i); 180 | unsigned size = *(unsigned *)(dumpData + i + 4); 181 | if (magic == 'illb') { 182 | int len = size; 183 | const char *ptr = dumpData + i + 8; 184 | llb = makeData(dumpData + i + 8, size); 185 | while (len > 0) { 186 | AppleImg3Header *hdr; 187 | if (len < sizeof(AppleImg3Header)) { 188 | break; 189 | } 190 | hdr = (AppleImg3Header *)ptr; 191 | flipAppleImg3Header(hdr); 192 | switch (hdr->magic) { 193 | case IMG3_ECID_MAGIC: 194 | ecid = (AppleImg3Header *)ptr; 195 | break; 196 | case IMG3_CERT_MAGIC: 197 | cert = (AppleImg3Header *)ptr; 198 | break; 199 | } 200 | len -= hdr->size; 201 | ptr += hdr->size; 202 | } 203 | break; 204 | } 205 | i += 8 + size; 206 | } 207 | if (!llb || !ecid || !cert) { 208 | XLOG(0, "FATAL: LLB blob corrupted or not found\n"); 209 | exit(1); 210 | } 211 | for (i = 0; i < fileLength - 8; ) { 212 | unsigned magic = *(unsigned *)(dumpData + i); 213 | unsigned size = *(unsigned *)(dumpData + i + 4); 214 | if (magic == 'SCAB') { 215 | DataValue *ticket = makeData(dumpData + i + 8, size); 216 | addValueToDictionary(signDict, "APTicket", (DictValue *)ticket); 217 | } else { 218 | const char *component = componentName(magic); 219 | DataValue *p = findPartialDigest(manifest, component); 220 | if (p) { 221 | Dictionary *dict = createRoot(""); 222 | DataValue *partialDigest = makeData(p->value, p->len); 223 | DataValue *blob = llb; 224 | if (magic != 'illb') { 225 | blob = makeBlob(ecid, cert, dumpData + i + 8, size); 226 | } 227 | addValueToDictionary(dict, "Blob", (DictValue *)blob); 228 | addValueToDictionary(dict, "PartialDigest", (DictValue *)partialDigest); 229 | free(dict->dValue.key); // hack 230 | addValueToDictionary(signDict, component, (DictValue *)dict); 231 | } 232 | } 233 | i += 8 + size; 234 | } 235 | 236 | plist = getXmlFromRoot(signDict); 237 | releaseDictionary(signDict); 238 | 239 | dumpFile = createAbstractFileFromFile(fopen(argv[2], "w")); 240 | dumpFile->write(dumpFile, plist, strlen(plist)); 241 | dumpFile->close(dumpFile); 242 | free(plist); 243 | 244 | memcpy(&thisecid, ecid + 1, 8); 245 | FLIPENDIANLE(thisecid); 246 | printf("saved blob for ECID=%lld\n", thisecid); 247 | 248 | free(dumpData); 249 | releaseDictionary(manifest); 250 | return 0; 251 | } 252 | #pragma GCC diagnostic pop 253 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/validate_ca.h: -------------------------------------------------------------------------------- 1 | unsigned char cerb[] = { 2 | 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02, 0x01, 3 | 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 4 | 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 5 | 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 6 | 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 7 | 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 8 | 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 9 | 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 10 | 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 11 | 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 12 | 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 13 | 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32, 0x35, 0x32, 0x31, 0x34, 14 | 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30, 0x39, 15 | 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 16 | 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 17 | 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 18 | 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 19 | 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 20 | 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 21 | 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 22 | 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 23 | 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 24 | 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 25 | 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 26 | 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe4, 0x91, 0xa9, 0x09, 27 | 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 28 | 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 29 | 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30, 0x02, 0xe8, 0x18, 0x3e, 30 | 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca, 0x66, 31 | 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 32 | 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 33 | 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1, 0xc9, 0x19, 0x72, 0xf5, 34 | 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, 0x55, 0x8f, 35 | 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 36 | 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 37 | 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac, 0x2c, 0x20, 0x6f, 0x70, 38 | 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d, 0xf3, 39 | 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e, 40 | 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 41 | 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c, 0x0d, 0xdb, 0x62, 0x16, 42 | 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41, 0xb3, 43 | 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 44 | 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, 0x83, 0x41, 45 | 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec, 0x5a, 0x04, 0x32, 0x8c, 46 | 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65, 0xbc, 47 | 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 48 | 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 49 | 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 50 | 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 51 | 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 52 | 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0, 0x69, 53 | 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 54 | 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 55 | 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 56 | 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 57 | 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 58 | 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00, 0x06, 59 | 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 60 | 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 61 | 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 62 | 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 63 | 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 64 | 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 65 | 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 66 | 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65, 0x72, 67 | 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 68 | 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 69 | 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 70 | 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 71 | 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 72 | 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 73 | 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 74 | 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 75 | 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 76 | 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 77 | 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 78 | 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63, 0x74, 79 | 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 80 | 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 81 | 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5c, 82 | 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3, 0x77, 83 | 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 84 | 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, 0x2c, 0xd4, 85 | 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b, 0xee, 0xd2, 0x64, 0x0f, 86 | 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b, 0xc8, 87 | 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 88 | 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 89 | 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3, 0xb7, 0x8b, 0x23, 0x3b, 90 | 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf, 0x0f, 91 | 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 92 | 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 93 | 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac, 0x8f, 0x73, 0x81, 0x60, 94 | 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, 0xf0, 0x60, 95 | 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 96 | 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 97 | 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c, 0x56, 0xeb, 0xda, 0x0f, 98 | 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f, 0xc1, 99 | 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71, 100 | 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 101 | 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63, 0xc8, 0x4b, 0x80, 0x17, 102 | 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37, 0xb0, 103 | 0x75, 0x75, 0x21 104 | }; 105 | unsigned int cerb_len = 1215; 106 | -------------------------------------------------------------------------------- /src/xpwn/ipsw-patch/xpwntool.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xpwn/libxpwn.h" 4 | #include "xpwn/nor_files.h" 5 | #include "xpwn/img3.h" 6 | 7 | #define BUFFERSIZE (1024*1024) 8 | 9 | int main(int argc, char* argv[]) { 10 | char* inData; 11 | size_t inDataSize; 12 | init_libxpwn(&argc, argv); 13 | 14 | if(argc < 3) { 15 | printf("usage: %s [-x24k|-xn8824k] [-t