Ultrasn0w

From The iPhone Wiki
Revision as of 23:14, 8 January 2009 by Planetbeing (talk | contribs) (Payload w/ Comments (by Darkmen) =)
Jump to: navigation, search

The first iPhone 3G unlock payload. Released on 01/01/09. [1]

Credit

MuscleNerd, and The dev team

Exploit

Relies on an unsigned code injection vulnerability.

The actual unlock works by a daemon patching the baseband's RAM on-the-fly, overriding the carrier lock code. It is not permanent because of the signature checks - the bootloader has to pass the sigchecks and the baseband has to pass them too, so any change to the baseband/bootloader cannot be made.

Current Injection Vector

yellowsn0w refers to the reuseable payload, but it requires an injection vector in order to be inserted into the baseband. yellowsn0w was originally to be released with an injection vector that works on pre-2.28.00 baseband versions. However, geohot had an injection vector for 2.28.00 and the decision was made to release yellowsn0w with this injection vector to benefit the most people.

The injection vector is discussed here

Payload w/ Comments (by Darkmen) =

Note that this analysis leaves out stage 2 of the injector and the comment on offset 4 of the "Code loader" is incorrect.

The exploit consists from 3 parts:

Code loader

ROM:00000000 ; =============== S U B R O U T I N E =======================================
ROM:00000000
ROM:00000000
ROM:00000000 loader
ROM:00000000                 LDR     R2, =0x11700    ; unused ram to place code
ROM:00000002                 ADDS    R4, R2, #1      ; thumb switch
ROM:00000004                 LDR     R3, =0x40159FBF ; at-handler buffer where StrToHex result of the at-command is
ROM:00000006
ROM:00000006 copy.loop                               ; CODE XREF: loader+12�j
ROM:00000006                 LDRB    R0, [R3]        ; copying code until double quotes
ROM:00000008                 CMP     R0, #0x22 ; '"'
ROM:0000000A                 BEQ     run             ; jump thumb code
ROM:0000000C                 STRB    R0, [R2]
ROM:0000000E                 ADDS    R2, #1
ROM:00000010                 ADDS    R3, #1
ROM:00000012                 B       copy.loop       ; copying code until double quotes
ROM:00000014 ; ---------------------------------------------------------------------------
ROM:00000014
ROM:00000014 run                                     ; CODE XREF: loader+A�j
ROM:00000014                 BX      R4              ; jump thumb code
ROM:00000014 ; End of function loader
ROM:00000014
ROM:00000014 ; ---------------------------------------------------------------------------

Task creator

RAM:000119A0 ; =============== S U B R O U T I N E =======================================
RAM:000119A0
RAM:000119A0
RAM:000119A0 handler_replace
RAM:000119A0                 LDR     R0, =0x4011714C ; soft reset handler addr
RAM:000119A2                 ADR     R1, new_handler
RAM:000119A4                 ADDS    R1, #1          ; thumbing
RAM:000119A6                 STR     R1, [R0]        ; setting new handler
RAM:000119A8                 POP     {R0-R4,PC}      ; safe exit fixing stack
RAM:000119A8 ; End of function handler_replace

RAM:000119B0 ; =============== S U B R O U T I N E =======================================
RAM:000119B0
RAM:000119B0
RAM:000119B0 new_handler                             ; DATA XREF: handler_replace+2�o
RAM:000119B0                 PUSH    {R4-R7,LR}
RAM:000119B2                 LDR     R3, =0x403BB344 ; jamptable var
RAM:000119B4                 MOVS    R6, #0x80
RAM:000119B6                 SUB     SP, SP, #0x2C
RAM:000119B8                 LSLS    R6, R6, #4      ; 0x200
RAM:000119BA                 STRH    R0, [R3]        ; saving R0 to mem var
RAM:000119BC                 STR     R1, [SP,#0x40+resp_string] ; saving responce prt to stack
RAM:000119BE                 LDR     R4, =0x201420AC ; malloc
RAM:000119C0                 ADDS    R0, R6, #0
RAM:000119C2                 BLX     R4              ; malloc(0x200)
RAM:000119C4                 MOVS    R5, #0
RAM:000119C6                 STR     R0, [SP,#0x40+ptr_200] ; saving pointer to stack
RAM:000119C8                 MOVS    R0, #0x98       ; sizeof(NU_TASK)
RAM:000119CA                 BLX     R4              ; malloc(0x98)
RAM:000119CC                 ADDS    R7, R0, #0      ; R7 = task
RAM:000119CE                 STR     R5, [R0,#0xC]   ; task.field=0
RAM:000119D0                 MOVS    R0, 0x100
RAM:000119D4                 BLX     R4              ; malloc(0x100)
RAM:000119D6                 MOVS    R2, #0x80
RAM:000119D8                 LDR     R1, =task_loop  ; src
RAM:000119DA                 LSLS    R2, R2, #1      ; size to copy
RAM:000119DC                 LDR     R3, =0x203C58A0 ; bytecpy
RAM:000119DE                 ADDS    R4, R0, #0      ; R4 = dyn_task_loop
RAM:000119E0                 BLX     R3              ; bytecpy(task_loop, dyn_task_loop, 0x100)
RAM:000119E2                 LDR     R3, [SP,#0x40+ptr_200]
RAM:000119E4                 STR     R3, [SP,#4]     ; void *stack_address = malloc(0x200)
RAM:000119E6                 MOVS    R3, #0x44
RAM:000119E8                 STR     R3, [SP,#0xC]   ; priority = 0x44
RAM:000119EA                 MOVS    R3, #0xA
RAM:000119EC                 ADDS    R4, #1          ; thumbing dyn_task_loop
RAM:000119EE                 STR     R3, [SP,#0x14]  ; preempt = NU_PREEMPT
RAM:000119F0                 MOVS    R3, #0xC
RAM:000119F2                 ADDS    R2, R4, #0      ; void(*task_entry)
RAM:000119F4                 STR     R3, [SP,#0x18]  ; auto_start = NU_START
RAM:000119F6                 LDR     R1, =devteam1   ; char *name
RAM:000119F8                 STR     R5, [SP]        ; void *argv = 0
RAM:000119FA                 STR     R6, [SP,#8]     ; stack_size = 0x200
RAM:000119FC                 STR     R5, [SP,#0x10]  ; time_slice = 0
RAM:000119FE                 ADDS    R0, R7, #0      ; NU_TASK *task
RAM:00011A00                 MOVS    R3, #0          ; int argc = 0
RAM:00011A02                 LDR     R4, =0x203FB540 ; NU_Create_Task
RAM:00011A04                 BLX     R4              ; status = NU_Create_Task()
RAM:00011A06                 ADDS    R2, R0, #0
RAM:00011A08                 CMP     R0, #0          ; success = zero
RAM:00011A0A                 BNE     status_error
RAM:00011A0C                 LDR     R1, =OK
RAM:00011A0E                 LDR     R0, [SP,#0x40+resp_string]
RAM:00011A10                 LDR     R3, =0x2046DD00 ; sprintf
RAM:00011A12                 BLX     R3              ; sprintf(resp_string,"OK")
RAM:00011A14                 B       exit            ; fixing stack
RAM:00011A16 ; ---------------------------------------------------------------------------
RAM:00011A16
RAM:00011A16 status_error                            ; CODE XREF: new_handler+5A�j
RAM:00011A16                 LDR     R1, =ERROR
RAM:00011A18                 LDR     R0, [SP,#0x40+resp_string]
RAM:00011A1A                 LDR     R3, =0x2046DD00 ; sprintf
RAM:00011A1C                 BLX     R3              ; sprintf(resp_string,"ERROR")
RAM:00011A1E
RAM:00011A1E exit                                    ; CODE XREF: new_handler+64�j
RAM:00011A1E                 ADD     SP, SP, #0x2C   ; fixing stack
RAM:00011A20                 POP     {R4-R7,PC}      ; bye
RAM:00011A20 ; End of function new_handler
RAM:00011A20
RAM:00011A20 ; ---------------------------------------------------------------------------

Unlock task loop

RAM:00011A64 ; =============== S U B R O U T I N E =======================================
RAM:00011A64
RAM:00011A64 task_loop                               ; DATA XREF: RAM:off_11A2C�o
RAM:00011A64                 PUSH    {R4,R5,LR}
RAM:00011A66                 LDR     R5, =0x40232754 ; sec mailbox
RAM:00011A68                 SUB     SP, SP, #0x14
RAM:00011A6A
RAM:00011A6A loop                                    ; CODE XREF: task_loop+44�j
RAM:00011A6A                 LDR     R3, =0x20165998 ; NU_Receive_From_Mailbox
RAM:00011A6C                 ADDS    R0, R5, #0      ; NU_MAILBOX *mailbox
RAM:00011A6E                 MOV     R1, SP          ; void *Message
RAM:00011A70                 MOVS    R2, #0xFF       ; Timeout
RAM:00011A72                 BLX     R3              ; NU_Receive_From_Mailbox(sec_mailbox,SP,0xFF)
RAM:00011A74                 LDR     R3, [SP]        ; Message[0]
RAM:00011A76                 CMP     R3, #0xD        ; Message[0] = 0xD ?
RAM:00011A78                 BNE     skip            ; 
RAM:00011A7A                 LDR     R1, [SP,#4]     ; Message[1]
RAM:00011A7C                 LDR     R3, =0x402F79BC
RAM:00011A7E                 LDR     R2, [R1]        ; Message[1].field0
RAM:00011A80                 STR     R2, [R3]        ; sec_task_var1 = Message[1].field0
RAM:00011A82                 ADDS    R3, #4          ; 0x402F79C0
RAM:00011A84                 LDR     R2, [R1,#4]     ; Message[1].field1
RAM:00011A86                 STR     R2, [R3]        ; sec_task_var2 = Message[1].field1
RAM:00011A88                 LDR     R2, [R1,#8]     ; Message[1].field2
RAM:00011A8A                 LDR     R3, =0x100FF00
RAM:00011A8C                 STR     R3, [R2]        ; Message[1].field2[0] = 0x100FF00
RAM:00011A8E                 LDR     R3, =0x4020401
RAM:00011A90                 STR     R3, [R2,#4]     ; Message[1].field2[1] = 0x4020401
RAM:00011A92                 LDR     R3, =0x4040403
RAM:00011A94                 STR     R3, [R2,#8]     ; Message[1].field2[2] = 0x4040403
RAM:00011A96                 MOVS    R3, #1
RAM:00011A98                 STR     R3, [R1,#0xC]   ; Message[1].field3 = 1
RAM:00011A9A                 MOVS    R3, #0x20       
RAM:00011A9C                 STR     R3, [SP]        ; Message[0] = 0x20
RAM:00011A9E
RAM:00011A9E skip                                    ; CODE XREF: task_loop+14�j
RAM:00011A9E                 ADDS    R0, R5, #0      ; sec mailbox
RAM:00011AA0                 MOV     R1, SP          ; void *Message
RAM:00011AA2                 MOVS    R2, #0xFF       ; timeout
RAM:00011AA4                 LDR     R3, =0x203ED568
RAM:00011AA6                 BLX     R3              ; NU_Send_To_Mailbox()
RAM:00011AA8                 B       loop            ; NU_Receive_From_Mailbox
RAM:00011AA8 ; End of function task_loop

Source Code

The source code for yellowsn0w is now live [2]

Compatibility

Country Provider yellowsn0w Version SIM/USIM Ingoing Calls? Outgoing Calls? SMS? GPRS/EDGE? UMTS/HSDPA? Comments
Bermuda Mobility 0.9.5 SIM No No No No Not Available Still stops working after a while of regular use :(
Germany O2 <=0.9.4 SIM Yes Yes Yes Icon shown but not tested Icon shown but not tested
Israel IL Orange 0.9.5 USIM Yes Yes Yes Yes Yes Requires turning airplane mode on and off to get signal. After that, works perfectly.

Additional information: http://report.yellowsn0w.com/

See Also

External links