The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Tutorial:Odysseus Bundles
Odysseus is a tool to upgrade/downgrade 32-bit devices to an unsigned iOS version as long as the device has valid SHSH blobs for it. The tool was originally created by xerub.
In order for Odysseus to work, it needs bundles for the intended firmware. These bundles are composed of 4 files; 3 patches and 1 plist. The patch files contain patches to ASR, iBEC and iBSS to ensure that iDevice boots up while skipping certain verifications to ensure that unsigned firmware can be installed.
To be able to create the patches, one needs several files from related IPSW. In this tutorial, we will be using the iPhone5,1 9.3.3 IPSW.
After running this tutorial and creating the iPhone5,1 9.3.3 bundle, you can use the same logic to create other bundles as code will be similar.
WARNING: This tutorial is for advanced users. You are proceeding on your own risk, as patching something incorrectly will result in unintended consequences in addition to restoring to currently singed un-jailbroken firmware.
Contents
Getting Decrypted Files
- Download the iPhone5,1 9.3.3 IPSW. Alternatively, you can use partial-zip to grab the files below
- Change the extension from IPSW to ZIP, and grab the following files:
- 058-49199-034.dmg (Restore Ramdisk)
- kernelcache.release.n41
- Firmware/dfu/iBEC.n41.RELEASE.dfu
- Firmware/dfu/iBSS.n41.RELEASE.dfu
- Decrypt the files using Firmware Keys and xpwntool
- For all files except kernel:
xpwntool [file in] [file out] -k [key] -iv [key]
- For kernel, there are a couple of ways, but you can use Img3decrypt (Ruby) and lzssdec (C++ source):
img3decrypt.rb kernelcache.release.n41 [key] [iv] kernelcache.decrypted
(decrypts it)lzssdec -o 384 < kernelcache.decrypted > kernelcache.decrypted.arm
(decompresses the decrypted file, skipping a 384 byte header)
- For all files except kernel:
Notes:
- The filenames depend on iOS version and device. The ramdisk has a different filename for each version and device, while the other three have the same name across versions (with n41 corresponding to iPhone5,1)
- img3decrypt.rb pads the decrypted file with extra zeros that result in garbage data at the end of the file after decompression with lzssdec.
- On iOS 10 the kernelcache is not encrypted, meaning lzssdec should be used directly (it is still compressed).
Kernel Disassembly
We need to disassemble kernel in order to retreive offsets that we will use when patching iBEC. Load the final decrypted kernel file (kernelcache.decrypted.arm) using IDA, select "ARM Little Endian" under "Processor Type" and let it do its thing. When done, we will be looking for 2 offsets:
First Offset
- In IDA's right panel, search for "entitlements are not a dictionary". This will be in the "com.apple.driver.AppleMobileFileIntegrity" section
- Double click "loc_80775D12" right before the text we searched for
- Double click "sub_80776B2C", which is the 2nd BL in the instruction
- This will take you to an instruction similar to this:
com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C sub_80776B2C ; CODE XREF: sub_80775C88+9Ap com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C ; sub_80777068+44p com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C var_10 = -0x10 com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C com.apple.driver.AppleMobileFileIntegrity:__text:80776B2C PUSH {R4-R7,LR} com.apple.driver.AppleMobileFileIntegrity:__text:80776B2E ADD R7, SP, #0xC com.apple.driver.AppleMobileFileIntegrity:__text:80776B30 STR.W R8, [SP,#0xC+var_10]! com.apple.driver.AppleMobileFileIntegrity:__text:80776B34 MOV R4, R0 com.apple.driver.AppleMobileFileIntegrity:__text:80776B36 LDR R0, =(unk_80779E70 - 0x80776B44) com.apple.driver.AppleMobileFileIntegrity:__text:80776B38 MOVS R6, #1 com.apple.driver.AppleMobileFileIntegrity:__text:80776B3A LDRB.W R1, [R4],#1 com.apple.driver.AppleMobileFileIntegrity:__text:80776B3E LDR R2, =(unk_8077A270 - 0x80776B4E) com.apple.driver.AppleMobileFileIntegrity:__text:80776B40 ADD R0, PC ; unk_80779E70 com.apple.driver.AppleMobileFileIntegrity:__text:80776B42 ADD.W R3, R0, R1,LSL#2 com.apple.driver.AppleMobileFileIntegrity:__text:80776B46 LDRH.W R8, [R0,R1,LSL#2] com.apple.driver.AppleMobileFileIntegrity:__text:80776B4A ADD R2, PC ; unk_8077A270 com.apple.driver.AppleMobileFileIntegrity:__text:80776B4C MOVS R0, #0x13 com.apple.driver.AppleMobileFileIntegrity:__text:80776B4E LDRH R3, [R3,#2] com.apple.driver.AppleMobileFileIntegrity:__text:80776B50 MLA.W R5, R3, R0, R2
Record the offset for this sub, where in IDA it will show in bottom left of the right panel. Here, it will be "0x72CB2C".
This offset is needed to patch AppleMobileFileIntegrity.
Second Offset
- In IDA's right panel, search for "com.apple.security.sandbox:__text"
- If you don't see disassembled code (like above), then you need to convert to arm thumb mode. Press "cmd+G" when using mac, enter for "Value" "0x1" and press "Ok". You will then see disassembled code
- Continue search for "mac_label_get"
- Double click "sub_80EA3F70" for "mac_label_get" (the sub is found to the right of it)
- Double click "sub_80E96C58", which is a reference for that previous "sub_80EA3F70" (to the top after CODE XREF)
- This will take you to an instruction similar to this:
com.apple.security.sandbox:__text:80E4B270 loc_80E96C60 ; CODE XREF: sub_80E96C58+2j com.apple.security.sandbox:__text:80E4B270 ; sub_80E971E4+14p ... com.apple.security.sandbox:__text:80E96C60 PUSH {R4,R7,LR} com.apple.security.sandbox:__text:80E96C62 ADD R7, SP, #0xC+var_8 com.apple.security.sandbox:__text:80E96C64 MOV R4, R0 com.apple.security.sandbox:__text:80E96C66 CMP R4, #0 com.apple.security.sandbox:__text:80E96C68 BEQ loc_80E96CA6 com.apple.security.sandbox:__text:80E96C6A LDR R0, =(unk_80F14FE4 - 0x80E96C70) com.apple.security.sandbox:__text:80E96C6C ADD R0, PC ; unk_80F14FE4 com.apple.security.sandbox:__text:80E96C6E BL sub_80EA3F40 com.apple.security.sandbox:__text:80E96C72 LDR R0, =(dword_80F14FF0 - 0x80E96C78) com.apple.security.sandbox:__text:80E96C74 ADD R0, PC ; dword_80F14FF0 com.apple.security.sandbox:__text:80E96C76 LDR R1, [R0] com.apple.security.sandbox:__text:80E96C78 MOV R0, R4 com.apple.security.sandbox:__text:80E96C7A BL sub_80EA3F70 com.apple.security.sandbox:__text:80E96C7E MOV R4, R0 com.apple.security.sandbox:__text:80E96C80 CBZ R4, loc_80E96C9C com.apple.security.sandbox:__text:80E96C82 ADD.W R0, R4, #0x64 com.apple.security.sandbox:__text:80E96C86 DMB.W ISHST
Look for offset in IDA at "BL sub_80EA3F70". Here, it will be "0xE4CC7A".
This offset is needed to patch Sandbox, which goes together with first offset.
ASR Patch
- Grab the ASR file after mounting the decrypted Restore ramdisk found in "usr/sbin/" and load in IDA as above.
- In IDA's right panel, search for "failed signature"
- Calculate the value needed to do a branch from failed instruction to passed instruction (which should be before or after it). In this case, it will be from "176E4" to "1768C", which will be
D2 E7
- Apply patch by clicking in signtuare failed line, then by going in IDA to Edit->Patch Program->Change Byte, and replace the first bytes with
D2 E7
. Then Edit->Patch Program->Apply patches to input file, and check box for create a backup. You will notice the branch visually pointing from signtaure failed (text no longer visible) to signature passed - Run "ldid -s" on patched file
- Create a .patch file by diffing both files: bsdiff [original] [patched] asr.patch
- Alternatively, you can use this ASR patcher by /u/gjest to automatically patch ASR and produce a .patch file. The tool is currently in Beta.
Patching ASR (Apple System Restore) will enable us to skip verification of whether the rootfs had any modifications to it or not.
iBEC Patch
1) We first need to locate a code cave to add new code to it. Afterwards, we need to add new code that will utilize the offsets that we found in kernel to patch them. The code cave for iBEC is typically in 1A8 location.
- Load decrypted iBEC in IDA, and right panel, search for "0xFEEDFACE" and record its offset that will be "1A7AC". Calculate a branch from "1B4" (will show you why later) to that offset. This will be
1A F0 FA BA
- Update the kernel offsets we found earlier to arm thumb:
0x72CB2C = 0072 CB2C = 2CCB 7200
0xE4CC7A = 00E4 CC7A = 7ACC E400
- Open a program to edit hex like "Hex Fiend", and open decrypted iBEC. Click on left column to switch to hex view, and reduce size of window to fit 8 groups of bytes. Afterwards, construct new bytes to add to code cave, and notice where each byte goes in relation to the kernel offsets. Simply copy and paste into Hex Fiend at the appropriate line as below and save file (as a copy)
Line 001A0: 10FF 2FE1 FEFF FFEA 034A 044B C250 044A Line 001B0: 044B C250 1AF0 FABA 0120 7047 2CCB 7200 Line 001C0: 0020 0020 7ACC E400 0000 0000 0000 0000
- Open edited file in IDA. Select line at 1A8, and press "cmd+G" to enter thumb mode and enter "0x1" for Value. Afterwards, press "C" to convert code and lastly, press "P" to create new subroutine on line 1A8. It will look like this, where you can see the offsets that we found and there corresponding patches:
ROM:000001A8 sub_1A8 ; CODE XREF: sub_1A048+154p ROM:000001A8 ROM:000001A8 ROM:000001A8 ROM:000001A8 LDR R2, =0x47702001 ROM:000001AA LDR R3, =0x72CB2C ROM:000001AC STR R2, [R0,R3] ROM:000001AE LDR R2, =0x20002000 ROM:000001B0 LDR R3, =0xE4CC7A ROM:000001B2 STR R2, [R0,R3] ROM:000001B4 B.W loc_1A7AC ROM:000001B4 ; End of function sub_1A8 ROM:000001B4 ROM:000001B4 ; --------------------------------------------------------------------------- ROM:000001B8 dword_1B8 DCD 0x47702001 ; DATA XREF: sub_1A8r ROM:000001BC dword_1BC DCD 0x72CB2C ; DATA XREF: sub_1A8+2r ROM:000001C0 dword_1C0 DCD 0x20002000 ; DATA XREF: sub_1A8+6r ROM:000001C4 dword_1C4 DCD 0xE4CC7A ; DATA XREF: sub_1A8+8r
Also, here you can see the "1B4" that we chose earlier for branch.
2) Goto "sub_1A7AC" (where we found "0xFEEDFACE"), then go to Edit->Functions->Delete Function and confirm
3) Highlight the newly deleted area, and go to Edit->Functions->Append Function Tail, and select "sub_1A8"
4) In IDA's right panel, search for "loc_1A7AC". This will be found as part of a BL as below.
ROM:0001A194 loc_1A194 ; CODE XREF: sub_1A048+136j ROM:0001A194 CMP R1, #0 ROM:0001A196 BEQ loc_1A0F0 ROM:0001A198 MOV R0, R6 ROM:0001A19A STR R1, [SP,#0x80+var_5C] ROM:0001A19C BL loc_1A7AC ROM:0001A1A0 CMP R0, #1
In this instruction, we need to change the BL to be the new "sub_1A8" instead of "loc_1A7AC". It will be from "1A19C" to "1A8" so E6 F7 04 F8
needs to be patched at beginning as shown earlier.
5) In IDA's right panel, search for "0xBFF01199", and change to "0x80000000". This will be 00 00 00 80
in bytes.
0xBFF01199 is the memory address of the go command handler (at byte offset 0x44 there is a reference to 0xBFF00000, which is the base address. Rebase to this and jump to 0xBFF01199 to get to the subroutine). This patch is needed for TBD
6) In IDA's right panel, search for "0x496D6733", and delete the sub after it, "sub_17F54":
ROM:00017F48 ; --------------------------------------------------------------------------- ROM:00017F4A ALIGN 4 ROM:00017F4C dword_17F4C DCD 0x496D6733 ; DATA XREF: sub_17E9C+14r ROM:00017F50 dword_17F50 DCD 0x20001 ; DATA XREF: sub_17E9C+5Cr ROM:00017F54 ROM:00017F54 ; =============== S U B R O U T I N E ======================================= ROM:00017F54 ROM:00017F54 ; Attributes: bp-based frame ROM:00017F54 ROM:00017F54 sub_17F54 ; CODE XREF: sub_18610+1A4p ROM:00017F54 ROM:00017F54 var_58 = -0x58 ROM:00017F54 var_54 = -0x54 ROM:00017F54 var_50 = -0x50 ROM:00017F54 var_4C = -0x4C ROM:00017F54 var_48 = -0x48 ROM:00017F54 var_44 = -0x44 ROM:00017F54 var_40 = -0x40 ROM:00017F54 var_3C = -0x3C ROM:00017F54 var_38 = -0x38 ROM:00017F54 var_34 = -0x34 ROM:00017F54 var_30 = -0x30 ROM:00017F54 var_1C = -0x1C ROM:00017F54 ROM:00017F54 PUSH {R4-R7,LR} ROM:00017F56 ADD R7, SP, #0xC ROM:00017F58 PUSH.W {R8,R10,R11} ROM:00017F5C SUB SP, SP, #0x40 ROM:00017F5E MOVW R6, #0x5394 ROM:00017F62 MOV R8, R0 ROM:00017F64 MOVT.W R6, #0xBFF4 ROM:00017F68 MOV R11, R2 ROM:00017F6A LDR R6, [R6]
This patch is needed for TBD
(This subroutine references the magic numbers of three IMG3 tags, namely ECID, SHSH and CERT. It is thus likely that it is evaluating SHSH blobs, which is why it must be patched out.)
7) In IDA's right panel, search for BL loc_17F54
found in this instruction:
ROM:0001878E loc_1878E ; CODE XREF: sub_18610+318j ROM:0001878E BL sub_38634 ROM:00018792 MOV R1, R0 ROM:00018794 MOVS R0, #0 ROM:00018796 STRB.W R0, [SP,#0xA8+var_6D] ROM:0001879A LDR R0, [SP,#0xA8+var_64] ROM:0001879C CMP R0, #0 ROM:0001879E BEQ.W loc_18BCE ROM:000187A2 CMP R1, #0 ROM:000187A4 LDR R5, [R6,#0x10] ROM:000187A6 IT NE ROM:000187A8 ORRNE.W R4, R4, #4 ROM:000187AC ADD.W R3, SP, #0xA8+var_6D ROM:000187B0 MOV R1, R8 ROM:000187B2 MOV R2, R4 ROM:000187B4 BL loc_17F54 ROM:000187B8 CBNZ R0, loc_187BE ROM:000187BA MOVS R5, #0 ROM:000187BC B loc_187D8
Change the BL to MOVS and STR like below. Just click on the BL, and edit bytes to be: 00 20 18 60
ROM:0001878E loc_1878E ; CODE XREF: sub_18610+318j ROM:0001878E BL sub_38634 ROM:00018792 MOV R1, R0 ROM:00018794 MOVS R0, #0 ROM:00018796 STRB.W R0, [SP,#0xA8+var_6D] ROM:0001879A LDR R0, [SP,#0xA8+var_64] ROM:0001879C CMP R0, #0 ROM:0001879E BEQ.W loc_18BCE ROM:000187A2 CMP R1, #0 ROM:000187A4 LDR R5, [R6,#0x10] ROM:000187A6 IT NE ROM:000187A8 ORRNE.W R4, R4, #4 ROM:000187AC ADD.W R3, SP, #0xA8+var_6D ROM:000187B0 MOV R1, R8 ROM:000187B2 MOV R2, R4 ROM:000187B4 MOVS R0, #0 ROM:000187B6 STR R0, [R3] ROM:000187B8 CBNZ R0, loc_187BE ROM:000187BA MOVS R5, #0 ROM:000187BC B loc_187D8
This patch is needed to remove reference to deleted instruction earlier.
8) In IDA's right panel, search for CBNZ R0, loc_38E90
found in this instruction:
ROM:00038E3C loc_38E3C ; CODE XREF: sub_38D0C+11Ej ROM:00038E3C LDR R0, =0xBFF00328 ROM:00038E3E ADD R1, SP, #0xD0+var_98 ROM:00038E40 MOVS R2, #0x80 ; 'Ç' ROM:00038E42 LDR R0, [R0] ROM:00038E44 BL sub_352DC ROM:00038E48 CBNZ R0, loc_38E90 ROM:00038E4A ROM:00038E4A loc_38E4A ; CODE XREF: sub_38D0C+ECj ROM:00038E4A CMP.W R8, #0 ROM:00038E4E BEQ loc_38E96
We will change CBNZ to NOP, and change CMP.W below it to MOVS.W
ROM:00038E3C loc_38E3C ; CODE XREF: sub_38D0C+11Ej ROM:00038E3C LDR R0, =0xBFF00328 ROM:00038E3E ADD R1, SP, #0xD0+var_98 ROM:00038E40 MOVS R2, #0x80 ; 'Ç' ROM:00038E42 LDR R0, [R0] ROM:00038E44 BL sub_352DC ROM:00038E48 NOP ROM:00038E4A ROM:00038E4A loc_38E4A ; CODE XREF: sub_38D0C+ECj ROM:00038E4A MOVS.W R8, #0 ROM:00038E4E BEQ loc_38E96
Just click on the CBNZ, and edit bytes to be: 00 BF 5F F0 00 08
This patch is needed for TBD
9) Create a .patch file by diffing both files: bsdiff [original] [patched] ibec.patch
iBSS Patch
- Load the decrypted iBSS file. In IDA's right panel, search for "0x496D6733", and delete the sub after it "sub_6228". This procedure references the same IMG3 tag magic numbers as the iBEC procedure deleted above, meaning that this patch is likely there to disable the evaluation of SHSH blobs.
ROM:0000621C ; --------------------------------------------------------------------------- ROM:0000621E ALIGN 0x10 ROM:00006220 dword_6220 DCD 0x496D6733 ; DATA XREF: sub_6170+14r ROM:00006224 dword_6224 DCD 0x20001 ; DATA XREF: sub_6170+5Cr ROM:00006228 ROM:00006228 ; =============== S U B R O U T I N E ======================================= ROM:00006228 ROM:00006228 ; Attributes: bp-based frame ROM:00006228 ROM:00006228 sub_6228 ; CODE XREF: sub_655C+126p ROM:00006228 ROM:00006228 var_58 = -0x58 ROM:00006228 var_54 = -0x54 ROM:00006228 var_50 = -0x50 ROM:00006228 var_4C = -0x4C ROM:00006228 var_48 = -0x48 ROM:00006228 var_44 = -0x44 ROM:00006228 var_40 = -0x40 ROM:00006228 var_3C = -0x3C ROM:00006228 var_38 = -0x38 ROM:00006228 var_34 = -0x34 ROM:00006228 var_30 = -0x30 ROM:00006228 var_1C = -0x1C ROM:00006228 ROM:00006228 PUSH {R4-R7,LR} ROM:0000622A ADD R7, SP, #0xC ROM:0000622C PUSH.W {R8,R10,R11} ROM:00006230 SUB SP, SP, #0x40 ROM:00006232 MOVW R6, #0x3090 ROM:00006236 MOV R8, R0 ROM:00006238 MOVT.W R6, #0x1001 ROM:0000623C MOV R11, R2 ROM:0000623E LDR R6, [R6]
- In IDA's right panel, search for
BL loc_6228
found in this instruction:
ROM:0000665A loc_665A ; CODE XREF: sub_655C+298j ROM:0000665A BL sub_E998 ROM:0000665E MOV R1, R0 ROM:00006660 MOVS R0, #0 ROM:00006662 STRB.W R0, [SP,#0xA0+var_6D] ROM:00006666 LDR R0, [SP,#0xA0+var_64] ROM:00006668 CMP R0, #0 ROM:0000666A BEQ.W loc_6AC2 ROM:0000666E CMP R1, #0 ROM:00006670 LDR.W R8, [R6,#0x10] ROM:00006674 IT NE ROM:00006676 ORRNE.W R5, R5, #4 ROM:0000667A ADD.W R3, SP, #0xA0+var_6D ROM:0000667E MOV R1, R4 ROM:00006680 MOV R2, R5 ROM:00006682 BL loc_6228 ROM:00006686 CBNZ R0, loc_66A0 ROM:00006688 MOVS R5, #0 ROM:0000668A B loc_66B6
- Change the BL to MOVS and STR like below. Just click on the BL, and edit bytes to be:
00 20 18 60
. This patch is needed to remove reference to deleted instruction earlier.
ROM:0000665A loc_665A ; CODE XREF: sub_655C+298j ROM:0000665A BL sub_E998 ROM:0000665E MOV R1, R0 ROM:00006660 MOVS R0, #0 ROM:00006662 STRB.W R0, [SP,#0xA0+var_6D] ROM:00006666 LDR R0, [SP,#0xA0+var_64] ROM:00006668 CMP R0, #0 ROM:0000666A BEQ.W loc_6AC2 ROM:0000666E CMP R1, #0 ROM:00006670 LDR.W R8, [R6,#0x10] ROM:00006674 IT NE ROM:00006676 ORRNE.W R5, R5, #4 ROM:0000667A ADD.W R3, SP, #0xA0+var_6D ROM:0000667E MOV R1, R4 ROM:00006680 MOV R2, R5 ROM:00006682 MOVS R0, #0 ROM:00006684 STR R0, [R3] ROM:00006686 CBNZ R0, loc_66A0 ROM:00006688 MOVS R5, #0 ROM:0000668A B loc_66B6
- In IDA's right panel, search for
CBNZ R0, loc_38E90
found in this instruction:
ROM:0000F004 loc_F004 ; CODE XREF: sub_EED4+11Ej ROM:0000F004 LDR R0, =0x10000328 ROM:0000F006 ADD R1, SP, #0xD0+var_98 ROM:0000F008 MOVS R2, #0x80 ; 'Ç' ROM:0000F00A LDR R0, [R0] ROM:0000F00C BL sub_E138 ROM:0000F010 CBNZ R0, loc_F058 ROM:0000F012 ROM:0000F012 loc_F012 ; CODE XREF: sub_EED4+ECj ROM:0000F012 CMP.W R8, #0 ROM:0000F016 BEQ loc_F05E
- We will change CBNZ to NOP, and change CMP.W below it to MOVS.W
ROM:0000F004 loc_F004 ; CODE XREF: sub_EED4+11Ej ROM:0000F004 LDR R0, =0x10000328 ROM:0000F006 ADD R1, SP, #0xD0+var_98 ROM:0000F008 MOVS R2, #0x80 ; 'Ç' ROM:0000F00A LDR R0, [R0] ROM:0000F00C BL sub_E138 ROM:0000F010 NOP ROM:0000F012 ROM:0000F012 loc_F012 ; CODE XREF: sub_EED4+ECj ROM:0000F012 MOVS.W R8, #0 ROM:0000F016 BEQ loc_F05E
- Just click on the CBNZ, and edit bytes to be:
00 BF 5F F0 00 08
. This patch is the same as the last iBEC patch above, and is needed for TBD. - Create a .patch file by diffing both files:
bsdiff [original] [patched] ibss.patch
Create Plist File
Plist file contains info taken from Firmware Keys page. Just open a file from another bundle, and edit it to add updated keys and other info
Create Bundle
Copy the 3 patch files and the plist file to a folder, and rename folder to: "Down_iPhone5,1_9.3.3_13G34.bundle"
Credits
@xerub: creating Odysseus
/u/HaniAG: this tutorial
/u/gjest: ASR patcher
@iSuns9: providing details for kernel offsets