Guesses
Diagnostic - bit 4 set
Debug - bit 5 set
Software Engineer - bit 8 set
Hardware Engineer - bit 17 set
Notes
Initial
Initially, boot flags are set to 0x2C0000, or:
| Bit | Set? |
| 0 | No |
| 1 | No |
| 2 | No |
| 3 | No |
| 4 | No |
| 5 | No |
| 6 | No |
| 7 | No |
| 8 | No |
| 9 | No |
| 10 | No |
| 11 | No |
| 12 | No |
| 13 | No |
| 14 | No |
| 15 | No |
| 16 | No |
| 17 | No |
| 18 | Yes |
| 19 | Yes |
| 20 | No |
| 21 | Yes |
| 22 | No |
| 23 | No |
| 24 | No |
| 25 | No |
| 26 | No |
| 27 | No |
| 28 | No |
| 29 | No |
| 30 | No |
| 31 | No |
Check 1: If either bit 0 or bit 5 of the device's CHPID is set, then bit 28 and 29 of the iBoot flags are set.
Check 2: If bit 5 of the device's CHPID is set, bits 15 and 20 of the iBoot flags are set.
Commands
| Command | Bits |
| powernvram | Check if bit 8 is set to allow usage of this command, and check if bit is set 17 to allow usage of the 'set' subcommand |
| diags | Check if bit 4 is set to allow usage of diags address to execute code. |
| charge | Check if bits 8 and 17 are set to allow usage of this command. |
| bdev | Check if bit 8 is set to allow usage of this command. |
| pki | Check if bit 8 is set to allow usage of this command. |
| image | Check if bit 8 is set to allow usage of this command. |
| iic | Check if bit 17 is set to allow usage of this command. |
| chunk | Check if bit 8 is set to allow usage of this command. |
Undocumented Routine
This stuff is from an interesting (and long) routine that I am not quite sure what it does, it has something to do with the 'bootx' command though, I think.
| Thing | Bits |
| System-Trusted | Check if bit 29 is set. |
| Secure-Boot | Check if bit 28 is set. |
| uid-aes-key | Check if bit 19 is set. |
| gid-aes-key | Check if bit 18 is set. |
| production-cert | Check if bit 21 is set. |
| development-cert | Check if bit 20 is set. |
| debug-enabled | Check if bit 5 is set. |
Range Check
If bit 16 is set, range check is bypassed.
Reversing
Reversings of various routines that relate to the iBoot flags in an effort to find out what does what.
Setup Range
ROM:0FF0BD38 ; =============== S U B R O U T I N E =======================================
ROM:0FF0BD38
ROM:0FF0BD38 ; logic:
ROM:0FF0BD38 ; if running on a special engineering / debug device, return.
ROM:0FF0BD38 ; if 'option' is not set to 0, then set mimimum address to -1 and maximum address to 0. then return. wtf?
ROM:0FF0BD38 ; if new_min is higher or equal to the current minimum address, don't set it.
ROM:0FF0BD38 ; if new_max is lower or equal to the current maximum address, don't set it.
ROM:0FF0BD38
ROM:0FF0BD38 ; void __cdecl Set_Up_Allowed_Range(__int32 new_min, __int32 new_max, int option)
ROM:0FF0BD38 Set_Up_Allowed_Range ; CODE XREF: sub_FF07682+B9Ep
ROM:0FF0BD38 ; sub_FF0BD7C+6Ep
ROM:0FF0BD38 new_min = R0 ; new minimum allowed address to be set
ROM:0FF0BD38 new_max = R1 ; this one is weird. it should be new maximum address minus the new minimum
ROM:0FF0BD38 000 10 B5 PUSH {R4,LR} ; Push registers
ROM:0FF0BD3A 008 0D 4B LDR R3, =iBoot_flags ; Load from Memory
ROM:0FF0BD3C 008 41 18 ADDS new_max, new_min, new_max ; new_max + new_min = real new maximum (wtf?)
ROM:0FF0BD3E 008 1B 68 LDR R3, [R3] ; Load from Memory
ROM:0FF0BD40 008 DC 03 LSLS R4, R3, #0xF ; Logical Shift Left
ROM:0FF0BD42 008 13 D4 BMI return ; if bit 16 is set, return.
ROM:0FF0BD42 ;
ROM:0FF0BD42 ; by the looks of it, bit 16 is set when the device is a special
ROM:0FF0BD42 ; engineering / debug device
ROM:0FF0BD44 008 00 2A CMP R2, #0 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD46 008 07 D0 BEQ set_minimum ; if the "option" arg is 0, jump here.
ROM:0FF0BD48
ROM:0FF0BD48 bad ; Load from Memory
ROM:0FF0BD48 008 0A 4A LDR R2, =Minimum_Allowed_Addr
ROM:0FF0BD4A 008 01 23 MOVS R3, #1 ; Rd = Op2
ROM:0FF0BD4C 008 5B 42 NEGS R3, R3 ; Negate
ROM:0FF0BD4E 008 13 60 STR R3, [R2] ; set minimum address to -1
ROM:0FF0BD50 008 09 4B LDR R3, =Maximum_Allowed_Addr ; Load from Memory
ROM:0FF0BD52 008 00 22 MOVS R2, #0 ; Rd = Op2
ROM:0FF0BD54 008 1A 60 STR R2, [R3] ; set maximum address to 0
ROM:0FF0BD56 008 09 E0 B return ; Branch
ROM:0FF0BD58 ; ---------------------------------------------------------------------------
ROM:0FF0BD58
ROM:0FF0BD58 set_minimum ; CODE XREF: Set_Up_Allowed_Range+Ej
ROM:0FF0BD58 008 06 4A LDR R2, =Minimum_Allowed_Addr ; Load from Memory
ROM:0FF0BD5A 008 13 68 LDR R3, [R2] ; Load from Memory
ROM:0FF0BD5C 008 98 42 CMP new_min, R3 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD5E 008 00 D2 BCS set_maximum ; if new_min is higher or the same as the current
ROM:0FF0BD5E ; minimum address, don't change anything.
ROM:0FF0BD60 008 10 60 STR new_min, [R2] ; set the minimum address to new_min
ROM:0FF0BD62
ROM:0FF0BD62 set_maximum ; CODE XREF: Set_Up_Allowed_Range+26j
ROM:0FF0BD62 008 05 4A LDR R2, =Maximum_Allowed_Addr ; Load from Memory
ROM:0FF0BD64 008 13 68 LDR R3, [R2] ; Load from Memory
ROM:0FF0BD66 008 99 42 CMP new_max, R3 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD68 008 00 D9 BLS return ; if new_max is less than or the same as the current
ROM:0FF0BD68 ; maximum address, don't change anything.
ROM:0FF0BD6A 008 11 60 STR new_max, [R2] ; set maximum address to new_max
ROM:0FF0BD6C
ROM:0FF0BD6C return ; CODE XREF: Set_Up_Allowed_Range+Aj
ROM:0FF0BD6C ; Set_Up_Allowed_Range+1Ej
ROM:0FF0BD6C ; Set_Up_Allowed_Range+30j
ROM:0FF0BD6C 008 10 BD POP {R4,PC} ; Pop registers
ROM:0FF0BD6C ; End of function Set_Up_Allowed_Range
ROM:0FF0BD6C
ROM:0FF0BD6C ; ---------------------------------------------------------------------------
ROM:0FF0BD6E 00 00 DCW 0
ROM:0FF0BD70 C0 86 F1 0F off_FF0BD70 DCD iBoot_flags ; DATA XREF: Set_Up_Allowed_Range+2r
ROM:0FF0BD74 C4 86 F1 0F off_FF0BD74 DCD Minimum_Allowed_Addr
ROM:0FF0BD74 ; DATA XREF: Set_Up_Allowed_Range:badr
ROM:0FF0BD74 ; Set_Up_Allowed_Range:set_minimumr
ROM:0FF0BD78 C8 86 F1 0F off_FF0BD78 DCD Maximum_Allowed_Addr
ROM:0FF0BD78 ; DATA XREF: Set_Up_Allowed_Range+18r
ROM:0FF0BD78 ; Set_Up_Allowed_Range:set_maximumrRange Check
ROM:0FF0BD04 ; =============== S U B R O U T I N E =======================================
ROM:0FF0BD04
ROM:0FF0BD04 ; iboot range check
ROM:0FF0BD04 ;
ROM:0FF0BD04 ; logic:
ROM:0FF0BD04 ; if running on a special dev board, we are good to go. bypasses the range check.
ROM:0FF0BD04 ; if unkown addr is negative for some reason, then fail.
ROM:0FF0BD04 ; if addr to check is less than the minimum addr defined at 0x0ff186c4, then fail.
ROM:0FF0BD04 ; if addr to check is greater than the maximum addr defined in 0xff186c8, then fail.
ROM:0FF0BD04 ;
ROM:0FF0BD04 ; psuedocode:
ROM:0FF0BD04 ; int permissions_check(long addr_to_check, long unk_addr) {
ROM:0FF0BD04 ; if(flags at 0x0ff186c0 << 0xF < 0) { // is bit 16 set?
ROM:0FF0BD04 ; return(1); // aka, success.
ROM:0FF0BD04 ; }
ROM:0FF0BD04 ; if(addr to check >= unk addr + addr to check) {
ROM:0FF0BD04 ; return(0); // aka, fail.
ROM:0FF0BD04 ; }
ROM:0FF0BD04 ; if(addr to check < min allowed addr) {
ROM:0FF0BD04 ; return(0); // aka, fail.
ROM:0FF0BD04 ; }
ROM:0FF0BD04 ; if(addr to check > max allowed addr) {
ROM:0FF0BD04 ; return(0); // aka, fail.
ROM:0FF0BD04 ; }
ROM:0FF0BD04 ;
ROM:0FF0BD04 ; return(1); // aka, success, since the other checks above passed
ROM:0FF0BD04 ; }
ROM:0FF0BD04
ROM:0FF0BD04 ; int __cdecl range_check(__int32 addr_to_check, __int32 unk_addr)
ROM:0FF0BD04 range_check ; CODE XREF: cmd_bootx+30p
ROM:0FF0BD04 ; cmd_diags+1Cp
ROM:0FF0BD04 ; sub_FF00BE8+64p
ROM:0FF0BD04 ; sub_FF00CA8+56p ...
ROM:0FF0BD04 000 09 4B LDR R3, =0xFF186C0 ; iboot flags
ROM:0FF0BD06 000 42 18 ADDS R2, R0, R1 ; r2 = addr to check + unknown addr
ROM:0FF0BD08 000 1B 68 LDR R3, [R3] ; flags located at 0x0ff186c0
ROM:0FF0BD0A 000 D9 03 LSLS R1, R3, #0xF ; Logical Shift Left
ROM:0FF0BD0C 000 09 D4 BMI return_success ; return(1); // good
ROM:0FF0BD0E 000 90 42 CMP R0, R2 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD10 000 09 D2 BCS return_fail ; return(0); // bad
ROM:0FF0BD12 000 07 4B LDR R3, =0xFF186C4 ; min addr
ROM:0FF0BD14 000 1B 68 LDR R3, [R3] ; Load from Memory
ROM:0FF0BD16 000 98 42 CMP R0, R3 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD18 000 05 D3 BCC return_fail ; return(0); // bad
ROM:0FF0BD1A 000 06 4B LDR R3, =0xFF186C8 ; max addr
ROM:0FF0BD1C 000 1B 68 LDR R3, [R3] ; Load from Memory
ROM:0FF0BD1E 000 9A 42 CMP R2, R3 ; Set cond. codes on Op1 - Op2
ROM:0FF0BD20 000 01 D8 BHI return_fail ; return(0); // bad
ROM:0FF0BD22
ROM:0FF0BD22 return_success ; CODE XREF: range_check+8j
ROM:0FF0BD22 000 01 20 MOVS R0, #1 ; return(1); // good
ROM:0FF0BD24 000 00 E0 B return ; Branch
ROM:0FF0BD26 ; ---------------------------------------------------------------------------
ROM:0FF0BD26
ROM:0FF0BD26 return_fail ; CODE XREF: range_check+Cj
ROM:0FF0BD26 ; range_check+14j
ROM:0FF0BD26 ; range_check+1Cj
ROM:0FF0BD26 000 00 20 MOVS R0, #0 ; return(0); // bad
ROM:0FF0BD28
ROM:0FF0BD28 return ; CODE XREF: range_check+20j
ROM:0FF0BD28 000 70 47 BX LR ; Branch to/from Thumb mode
ROM:0FF0BD28 ; End of function range_check
ROM:0FF0BD28
ROM:0FF0BD28 ; ---------------------------------------------------------------------------
ROM:0FF0BD2A 00 00 DCW 0
ROM:0FF0BD2C C0 86 F1 0F dword_FF0BD2C DCD 0xFF186C0 ; DATA XREF: range_checkr
ROM:0FF0BD30 C4 86 F1 0F dword_FF0BD30 DCD 0xFF186C4 ; DATA XREF: range_check+Er
ROM:0FF0BD34 C8 86 F1 0F dword_FF0BD34 DCD 0xFF186C8 ; DATA XREF: range_check+16rPermissions / Generic Flag Check
ROM:0FF0BCAC ; will check the given flag in the iboot flags
ROM:0FF0BCAC ;
ROM:0FF0BCAC ; logic:
ROM:0FF0BCAC ; if the iboot_flags do not contain the flag supplied to the routine, return 0 // bad
ROM:0FF0BCAC ; if the flags supplied to this routine does has bit 4 set, then set bit 5 in the iboot flags as well. return 1. // good
ROM:0FF0BCAC
ROM:0FF0BCAC ; int __cdecl flag_check(int flag)
ROM:0FF0BCAC flag_check ; CODE XREF: cmd_diags+26p
ROM:0FF0BCAC ; cmd_powernvram+Ep
ROM:0FF0BCAC ; cmd_powernvram+7Ep
ROM:0FF0BCAC ; cmd_charge+Cp ...
ROM:0FF0BCAC 000 10 B5 PUSH {R4,LR} ; Push registers
ROM:0FF0BCAE 008 08 49 LDR R1, =iBoot_flags ; Load from Memory
ROM:0FF0BCB0 008 00 24 MOVS R4, #0 ; Rd = Op2
ROM:0FF0BCB2 008 0A 68 LDR R2, [R1] ; Load from Memory
ROM:0FF0BCB4 008 13 1C ADDS R3, R2, #0 ; Rd = Op1 + Op2
ROM:0FF0BCB6 008 03 40 ANDS R3, R0 ; Rd = Op1 & Op2
ROM:0FF0BCB8 008 98 42 CMP R0, R3 ; check iboot flags against the supplied flags
ROM:0FF0BCBA 008 07 D1 BNE return ; return(0);
ROM:0FF0BCBC 008 01 24 MOVS R4, #1 ; Rd = Op2
ROM:0FF0BCBE 008 C3 06 LSLS R3, R0, #0x1B ; check if the supplied flags has bit 4 set
ROM:0FF0BCC0 008 04 D5 BPL return ; return(1);
ROM:0FF0BCC2 008 04 4B LDR R3, =0xDFF3FFFF ; Load from Memory
ROM:0FF0BCC4 008 13 40 ANDS R3, R2 ; Rd = Op1 & Op2
ROM:0FF0BCC6 008 20 22 MOVS R2, #0x20 ; Rd = Op2
ROM:0FF0BCC8 008 13 43 ORRS R3, R2 ; Rd = Op1 | Op2
ROM:0FF0BCCA 008 0B 60 STR R3, [R1] ; set bit 5 of the iboot flags
ROM:0FF0BCCC
ROM:0FF0BCCC return ; CODE XREF: flag_check+Ej
ROM:0FF0BCCC ; flag_check+14j
ROM:0FF0BCCC 008 20 1C ADDS R0, R4, #0 ; Rd = Op1 + Op2
ROM:0FF0BCCE 008 10 BD POP {R4,PC} ; Pop registers
ROM:0FF0BCCE ; End of function flag_checkThanks
MUCH thanks to CPICH for teaching me about all of this bitwise stuff that was really confusing to me at first
That means... the permission check is also very easy to bypass like you did with the rangecheck?
The range check wasn't bypassed. Neither is the permission check.
do you have a beta version??
LOL
musclenerd, why do you even come here and destroy these guys' hope? well, for NOW chronic may or may not have been able to patch anything, but it kind of looks bad when YOU (, not Chronic himself, westbaer, tom3q or anyone else from CDT) comes here to shut these non-experts off. atleast, that's what i think. i know that you're totally right, but.. it doesn't help that a member from ANOTHER dev-team comes to THIS dev-teams google code and say like: HEY! HE HASN'T DONE THAT!!!!! cuz'... that's kind of obvious. well. it would be better if you just wrote what you know has been or hasn't been done in a NICER way. even noobs deserve their help. all they DID was to ask some questions nicely. say what you want. :) have a good day!
btw.. :'D keep up the good work you guys are doing over at iphone-dev. :D good luck with the unlock! <3
pinnen92: MuscleNerd? is correct. I have stressed this mutliple times, but some people may have missed it. I do not really see it as destroying people's hope, because really he is just correcting someone that did not quite understand what was going on. This page and all of the wiki is just documentation of various things, no actual exploit / bypassing yet o.O
good to see that you are making progress..!!! cheers..
sorrry jejeje good luck :)
pinnen92:
My response to super's post was just a factual correction...I couldn't put it in any more neutral way. My response to cabreronski's post was more tongue in cheek because he'd brought things to a whole new level :)
MuscleNerd?: the dude u loled at was probably confused by your wording :P some people are not understanding the fact that this is just documentation, and in his mindset, he thought what you said was like "in the jailbreak, the method does not bypass the range check or permissions check", instead of what is true, "there is no current method of bypassing the range / permission check"
great progress guys keep the good work up. will what does all this iboot flags crap mean? how does this relate to a jailbreak? Thanks, A
boomwbb: i am documenting stuff from iBEC, which is like a slimmer and unencrypted iBoot
Stupid question… can i set boot flag at 0x2C0000?
I could be wrong here but I think in Set_Up_Allowed_Range? the confusion about the new_max is due to the fact that it is not a max. I think the arguments are a base address, a length, and a boolean (set defaults or not). new_max = base + length.
range check is addr + max size for a file. i just haven't updated this page in awhile :P