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 signed un-jailbroken firmware.

Getting Decrypted Files

 * 1) Download the iPhone5,1 9.3.3 IPSW. Alternatively, you can use partial-zip to grab the files below
 * 2) Change the extension from IPSW to ZIP, and grab the following files:
 * 3) * 058-49199-034.dmg (Restore Ramdisk)
 * 4) * kernelcache.release.n41
 * 5) * Firmware/dfu/iBEC.n41.RELEASE.dfu
 * 6) * Firmware/dfu/iBSS.n41.RELEASE.dfu
 * 7) Decrypt the files using Firmware Keys and xpwntool
 * 8) *For all files except kernel:
 * 9) *For kernel, there are a couple of ways, but you can use Img3decrypt (Ruby) and lzssdec (C++ source):
 * 10) *#  (decrypts it)
 * 11) *#  (decompresses the decrypted file, skipping a 384 byte header)

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

 * 1) In IDA's right panel, search for "entitlements are not a dictionary". This will be in the "com.apple.driver.AppleMobileFileIntegrity" section
 * 2) Double click "loc_80775D12" right before the text we searched for
 * 3) Double click "sub_80776B2C", which is the 2nd BL in the instruction
 * 4) 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

 * 1) In IDA's right panel, search for "com.apple.security.sandbox:__text"
 * 2) If you don't see disassembled code (like above), then you need to convert to arm thumb mode. Press "option+G" when using mac, enter for "Value" "0x1" and press "Ok". You will then see disassembled code
 * 3) Continue search for "mac_label_get"
 * 4) Double click "sub_80EA3F70" for "mac_label_get" (the sub is found to the right of it)
 * 5) Double click "sub_80E96C58", which is a reference for that previous "sub_80EA3F70" (to the top after CODE XREF)
 * 6) 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
 * Apply patch by clicking in signature failed line, then by going in IDA to Edit->Patch Program->Change Byte, and replace the first bytes with . Then Edit->Patch Program->Apply patches to input file, and check box for create a backup. You will notice the branch visually pointing from signature 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


 * Update the kernel offsets we found earlier to arm thumb:


 * 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 "option+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  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  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  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:

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  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:

This patch is needed for TBD

9) Create a .patch file by diffing both files: bsdiff [original] [patched] ibec.patch

iBSS Patch

 * 1) 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  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:. 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  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:. This patch is the same as the last iBEC patch above, and is needed for TBD.  Create a .patch file by diffing both files: 

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