From The Apple Wiki
(Redirected from Yellowsn0w)

ultrasn0w (previously: yellowsn0w) is an iPhone 3G, iPhone 3GS and iPhone 4 (iPhone3,1) unlock payload. yellowsn0w was released on New Years Day 2009[dead link]. ultrasn0w was released on 23 June 2009 [Archived 2009-06-25 at the Wayback Machine]. The official repository for ultrasn0w (repo666.ultrasn0w.com) has shut down.


MuscleNerd and iPhone Dev Team


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.

Injection Vectors[edit]

Compatible Basebands[edit]

iPhone 3G/3GS[edit]

  • 02.28.00 (yellowsn0w only)
  • 04.26.08
  • 05.11.07
  • 05.12.01
  • 05.13.04
  • 06.15.00

iPhone 4[edit]

  • 01.59.00 (if device is on iOS 5.x or lower)

ultrasn0w payload with comments (by Oranav)[edit]

Code loader (incl. Stage2)[edit]

ROM:00000000 ; =============== S U B R O U T I N E =======================================
ROM:00000000 code_loader
ROM:00000000 dest_addr = R1
ROM:00000000 src_addr = R6
ROM:00000000                 MOVLS   dest_addr, 0x110
ROM:00000004                 ADDS    dest_addr, #6
ROM:00000006                 LSLS    dest_addr, dest_addr, #8 ; unused ram to place code = 0x11600
ROM:00000008                 ADDS    R2, dest_addr, #1 ; thumbing
ROM:0000000A loop                                    ; CODE XREF: code_loader+24�j
ROM:0000000A                 MOVLS   R0, 0x22 ; '"'
ROM:0000000E                 LDRB    R3, [src_addr]  ; first nibble
ROM:00000010                 CMP     R0, R3
ROM:00000012                 LDRB    R0, [src_addr,#1] ; second nibble
ROM:00000014                 BEQ     run             ; branch if end of string
ROM:00000016                 SUBS    R3, #0x41       ; subtract 'A'
ROM:00000018                 SUBS    R0, #0x41       ; subtract 'A'
ROM:0000001A                 LSLS    R3, R3, #4      ; make room for next nibble
ROM:0000001C                 ADDS    R3, R3, R0      ; put them together as a byte
ROM:0000001E                 STRB    R3, [dest_addr]
ROM:00000020                 ADDS    dest_addr, #1
ROM:00000022                 ADDS    src_addr, #2
ROM:00000024                 B       loop
ROM:00000026 ; ---------------------------------------------------------------------------
ROM:00000026 run                                     ; CODE XREF: code_loader+14�j
ROM:00000026                 BLX     R2              ; handler_replace()
ROM:00000028                 MOVLS   R0, 0           ; safe exit
ROM:0000002C                 ADDS    dest_addr, R0, #0
ROM:0000002E                 BLX     R4
ROM:00000030                 MOV     SP, R5
ROM:00000032                 POP     {R0-src_addr,PC}
ROM:00000032 ; End of function code_loader

Handler replace[edit]

RAM:00011600 ; =============== S U B R O U T I N E =======================================
RAM:00011600 handler_replace
RAM:00011600                 PUSH    {LR}
RAM:00011602                 LDR     R0, =0x40492FC0 ; where to save task_loop_jmp + task_loop
RAM:00011604                 ADR     R1, task_loop_jmp
RAM:00011606                 ADR     R2, task_loop_end
RAM:00011608                 SUBS    R2, R2, R1      ; size of task_loop + task_loop_jmp = 0x70
RAM:0001160A                 LDR     R3, =0x2040882C ; memcpy()
RAM:0001160C                 BLX     R3
RAM:0001160E                 LDR     R0, =0x40492C20 ; where to save task_creator_jmp + task_creator
RAM:00011610                 ADR     R1, task_creator_jmp
RAM:00011612                 ADR     R2, task_creator_end
RAM:00011614                 SUBS    R2, R2, R1      ; size of task_creator + task_creator_jmp = 0xA0
RAM:00011616                 LDR     R3, =0x2040882C ; memcpy()
RAM:00011618                 BLX     R3
RAM:0001161A                 LDR     R0, =0x40492C20
RAM:0001161C                 BLX     R0              ; task_creator_jmp()
RAM:0001161E                 POP     {PC}
RAM:0001161E ; End of function handler_replace

Task creator (thanks Darkmen for the comments!)[edit]

RAM:40492C20 ; =============== S U B R O U T I N E =======================================
RAM:40492C20 task_creator_jmp
RAM:40492C20                 STMFD   SP!, {R1-R12,LR}
RAM:40492C24                 BLX     task_creator
RAM:40492C28                 LDMFD   SP!, {R1-R12,PC}
RAM:40492C28 ; End of function task_creator_jmp
RAM:40492C2C ; =============== S U B R O U T I N E =======================================
RAM:40492C2C task_creator                            ; CODE XREF: task_creator_jmp+4�p
RAM:40492C2C                 PUSH    {R4-R7,LR}
RAM:40492C2E                 LDR     R3, =0x401ED3B8 ; jumptable var
RAM:40492C30                 MOVLS   R4, 0x800
RAM:40492C34                 SUB     SP, SP, #0x24
RAM:40492C36                 STRH    R0, [R3]        ; task_creator_jmp addr
RAM:40492C38                 LDR     R5, =0x201493F0 ; malloc
RAM:40492C3A                 ADDS    R0, R4, #0      ; 0x800
RAM:40492C3C                 ADDS    R7, R1, #0      ; R7 = resp_string
RAM:40492C3E                 BLX     R5              ; malloc(0x800)
RAM:40492C40                 ADDS    R6, R0, #0      ; R6 = addr returned from malloc
RAM:40492C42                 MOVS    R0, #0x98       ; sizeof(NU_TASK)
RAM:40492C44                 BLX     R5              ; malloc(sizeof(NU_TASK))
RAM:40492C46                 MOVS    R2, #0
RAM:40492C48                 MOVS    R3, #0x44
RAM:40492C4A                 LDR     R1, =aDevteam1  ; char *name
RAM:40492C4C                 STR     R2, [R0,#0xC]   ; task.field=0
RAM:40492C4E                 STR     R3, [SP,#0xC]   ; priority = 0x44
RAM:40492C50                 MOVS    R3, #0xA
RAM:40492C52                 STR     R3, [SP,#0x14]  ; preempt = NU_PREEMPT
RAM:40492C54                 MOVS    R3, #0xC
RAM:40492C56                 STR     R2, [SP]        ; void *argv = 0
RAM:40492C58                 STR     R4, [SP,#8]     ; stack_size = 0x800
RAM:40492C5A                 STR     R2, [SP,#0x10]  ; time_slice = 0
RAM:40492C5C                 STR     R3, [SP,#0x18]  ; auto_start = NU_START
RAM:40492C5E                 LDR     R2, =0x40492FC0 ; task_loop_jmp address
RAM:40492C60                 STR     R6, [SP,#4]     ; void *stack_address = malloc(0x800)
RAM:40492C62                 MOVS    R3, #0
RAM:40492C64                 LDR     R4, =0x2043E5B4 ; NU_Create_Task
RAM:40492C66                 BLX     R4              ; status = NU_Create_Task()
RAM:40492C68                 ADDS    R2, R0, #0      ; R2 = status (for the %d reference in sprintf)
RAM:40492C6A                 CMP     R0, #0          ; success = zero
RAM:40492C6C                 BNE     status_error
RAM:40492C6E                 LDR     R1, =aOk        ; "OK!"
RAM:40492C70                 ADDS    R0, R7, #0      ; resp_string
RAM:40492C72                 LDR     R3, =0x204B11F0 ; sprintf
RAM:40492C74                 BLX     R3              ; sprintf(resp_string, "OK!")
RAM:40492C76                 B       exit
RAM:40492C78 ; ---------------------------------------------------------------------------
RAM:40492C78 status_error                            ; CODE XREF: task_creator+40�j
RAM:40492C78                 LDR     R1, =aErrorD    ; "ERROR %d"
RAM:40492C7A                 ADDS    R0, R7, #0      ; resp_string
RAM:40492C7C                 LDR     R3, =0x204B11F0 ; sprintf
RAM:40492C7E                 BLX     R3              ; sprintf(resp_string, "ERROR %d", status)
RAM:40492C80 exit                                    ; CODE XREF: task_creator+4A�j
RAM:40492C80                 ADD     SP, SP, #0x24   ; fixing stack
RAM:40492C82                 POP     {R4-R7,PC}
RAM:40492C82 ; End of function task_creator

Unlock task loop (thanks Darkmen for the comments!)[edit]

RAM:00011630 ; =============== S U B R O U T I N E =======================================
RAM:00011630 task_loop_jmp
RAM:00011630                 STMFD   SP!, {R1-R12,LR}
RAM:00011634                 BLX     task_loop
RAM:00011634 ; ---------------------------------------------------------------------------
RAM:00011638                 LDMFD   SP!, {R1-R12,PC}
RAM:00011638 ; End of function task_loop_jmp
RAM:0001163C ; =============== S U B R O U T I N E =======================================
RAM:0001163C task_loop
RAM:0001163C                 PUSH    {R4,R5,LR}
RAM:0001163E                 LDR     R5, =0x401E829C ; sec mailbox
RAM:00011640                 SUB     SP, SP, #0x14
RAM:00011642 loop                                    ; CODE XREF: task_loop+44�j
RAM:00011642                 LDR     R3, =0x2042FFD8 ; NU_Receive_From_Mailbox
RAM:00011644                 ADDS    R0, R5, #0      ; NU_MAILBOX *mailbox
RAM:00011646                 MOV     R1, SP          ; void *Message
RAM:00011648                 MOVS    R2, #0xFF       ; Timeout
RAM:0001164A                 BLX     R3              ; NU_Receive_From_Mailbox(sec_mailbox,SP,0xFF)
RAM:0001164C                 LDR     R3, [SP]        ; Message[0]
RAM:0001164E                 CMP     R3, #0xD        ; Message[0] = 0xD ?
RAM:00011650                 BNE     skip
RAM:00011652                 LDR     R1, [SP,#4]     ; Message[1]
RAM:00011654                 LDR     R3, =0x40301650
RAM:00011656                 LDR     R2, [R1]        ; Message[1].field0
RAM:00011658                 STR     R2, [R3]        ; sec_task_var1 = Message[1].field0
RAM:0001165A                 ADDS    R3, #4          ; 0x40301654
RAM:0001165C                 LDR     R2, [R1,#4]     ; Message[1].field1
RAM:0001165E                 STR     R2, [R3]        ; sec_task_var2 = Message[1].field1
RAM:00011660                 LDR     R2, [R1,#8]     ; Message[1].field2
RAM:00011662                 LDR     R3, =0x100FF00
RAM:00011664                 STR     R3, [R2]        ; Message[1].field2[0] = 0x100FF00
RAM:00011666                 LDR     R3, =0x4020401
RAM:00011668                 STR     R3, [R2,#4]     ; Message[1].field2[1] = 0x4020401
RAM:0001166A                 LDR     R3, =0x4040403
RAM:0001166C                 STR     R3, [R2,#8]     ; Message[1].field2[2] = 0x4040403
RAM:0001166E                 MOVS    R3, #1
RAM:00011670                 STR     R3, [R1,#0xC]   ; Message[1].field3 = 1
RAM:00011672                 MOVS    R3, #0x20 ; ' '
RAM:00011674                 STR     R3, [SP] ; Message[0] = 0x20
RAM:00011676 skip                                    ; CODE XREF: task_loop+14�j
RAM:00011676                 ADDS    R0, R5, #0      ; sec mailbox
RAM:00011678                 MOV     R1, SP          ; void *Message
RAM:0001167A                 MOVS    R2, #0xFF       ; timeout
RAM:0001167C                 LDR     R3, =0x20430040
RAM:0001167E                 BLX     R3              ; NU_Send_To_Mailbox()
RAM:00011680                 B       loop
RAM:00011680 ; End of function task_loop
RAM:00011680 ; ---------------------------------------------------------------------------

Old yellowsn0w payload w/ comments (by Darkmen)[edit]

The exploit consists from 4 parts:

Code loader[edit]

ROM:00000000 ; =============== S U B R O U T I N E =======================================
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 stage2 binary and following hexdata are
ROM:00000006 copy.loop                               ; CODE XREF: loader+12�j
ROM:00000006                 LDRB    R0, [R3]        ; copying code+data 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       ; 
ROM:00000014 run                                     ; CODE XREF: loader+A�j
ROM:00000014                 BX      R4              ; jump stage2 code
ROM:00000014 ; End of function loader
ROM:00000014 ; ---------------------------------------------------------------------------


RAM:00000000 ; =============== S U B R O U T I N E =======================================
RAM:00000000 stage2
RAM:00000000                 ADDS    R2, #0x10       ; R2 = 0x11700 + stage2 size
RAM:00000002                 MOVS    R7, #0xF
RAM:00000004                 BICS    R2, R7          ; align offset by 0x10
RAM:00000006                 ADDS    R7, R2, #0      ; saving address to jump
RAM:00000008                 ADR     R4, 0x44        ; skipping Stage2 size and taking first char from at-string
RAM:0000000A                 ADR     R5, char2byte   ; loading routine addr
RAM:0000000C                 ADDS    R5, #1          ; thumb
RAM:0000000E loop                                    ; CODE XREF: stage2+2C�j
RAM:0000000E                 LDRB    R1, [R4]        ; at-string[index]
RAM:00000010                 CMP     R1, #'x'        ; end of line?
RAM:00000012                 BEQ     jump_code
RAM:00000014                 BLX     R5              ; char2byte first hakfbyte
RAM:00000016                 LSLS    R3, R1, #4      ; <<4 0X becoming X0
RAM:00000018                 LDRB    R1, [R4,#1]     ; at-string[index+1]
RAM:0000001A                 BLX     R5              ; char2hex second halfbyte
RAM:0000001C                 NOP
RAM:0000001E                 NOP
RAM:00000020                 NOP
RAM:00000022                 NOP
RAM:00000024                 ADDS    R1, R1, R3      ; R1 = complete byte
RAM:00000026                 STRB    R1, [R2]        ; storing byte to dst
RAM:00000028                 ADDS    R4, #2          ; hexstr_index+=2
RAM:0000002A                 ADDS    R2, #1          ; dst++
RAM:0000002C                 B       loop            ; at-string[index]
RAM:0000002E jump_code
RAM:0000002E                 NOP
RAM:00000030                 NOP
RAM:00000032                 ADDS    R7, #1          ; thumbing
RAM:00000034                 BX      R7              ; run Task creator code
RAM:00000034 ; End of function stage2
RAM:00000038 ; =============== S U B R O U T I N E =======================================
RAM:00000038 char2byte                               ; DATA XREF: stage2+A�o
RAM:00000038                 CMP     R1, #0x41 ; 'A'
RAM:0000003A                 BGE     letter          ; letter to number
RAM:0000003C                 SUBS    R1, #0x30 ; '0' ; digit to number
RAM:0000003E                 BX      LR
RAM:00000040 letter                                  ; CODE XREF: char2byte+2�j
RAM:00000040                 SUBS    R1, #0x37 ; '7' ; letter to number
RAM:00000042                 BX      LR              ; ret
RAM:00000042 ; End of function char2byte

Task creator[edit]

RAM:000119A0 ; =============== S U B R O U T I N E =======================================
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 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 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 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 ; ---------------------------------------------------------------------------

Unlock task loop[edit]

RAM:00011A64 ; =============== S U B R O U T I N E =======================================
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 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 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

Explanation from planetbeing[edit]

13:24:29  <crash-x_> especially how does ultra/yellow sn0w work
13:24:40  <crash-x_> are you overwriting instructions
13:24:48  <crash-x_> or some values in memory to make it accept the sim?
13:24:48  <planetbeing> Nah.
13:24:53  <planetbeing> It's a task.
13:25:06  <planetbeing> That just waits for securiy messages to go through the inbox.
13:25:13  <westbaer> planetbeing: btw, why isnt yellowsn0w/ultrasn0w not open-source anymore? like u posted an *oooold* version once


13:26:33  <planetbeing> The only thing I do for ys/us is the loader bit.
13:26:39  <westbaer> so whats actually the loader stuff you've been talking about?
13:26:46  <planetbeing> That uses the exploit to start MuscleNerd's payload.
13:27:21  <westbaer> ah
13:27:26  <planetbeing> Well, you have a vulnerability.
13:27:30  <planetbeing> And you want to load a large chunk of code.
13:27:39  <planetbeing> And you don't have much room to wriggle in for your overflow
13:28:21  <westbaer> aah, makes sense
13:28:50  <planetbeing> So the solution is a small loader that loads the rest of the code, and overcomes any restrictions there are on allowable characters.
13:28:55  <ashikase> francis: pm
13:28:59  <westbaer> yeah
13:29:10  <crash-x_> planetbeing: the baseband is it like one process that runs there
13:29:19  <crash-x_> or is it like a small os with process and stuff
13:29:19  <planetbeing> Basically a good loader should turn a vulnerability into a reliable platform for the execution of arbitrary code, unrestricted by vulnerability-specific stuff.
13:29:37  <planetbeing> Oh, it's a full-featured OS.
13:29:38  <planetbeing> Nucleus.
13:29:51  <planetbeing> http://www.mentor.com/products/embedded_software/nucleus_rtos/
13:29:54  <crash-x_> and when you execute an at command
13:30:06  <crash-x_> does that start another process that is crashed then
13:30:21  <planetbeing> Ideally, you don't crash anything.
13:30:21  <crash-x_> or does it crash like the main baseband program
13:30:23  <planetbeing> And we don't.
13:30:49  <crash-x_> so am i understand it right
13:30:50  <westbaer> wait. is nucleus on the baseband already installed or do you actually inject it with ultrasn0w?
13:30:51  <planetbeing> We load a bunch of code into certain memory locations, execute them, and then return safely back to the main command parser task.
13:31:00  <planetbeing> Nucleus is what the baseband runs.
13:31:04  <westbaer> ah ok
13:31:29  <planetbeing> I mean, even the bootrom is an OS.
13:31:36  <planetbeing> With one task, but it still has a scheduler. =P
13:31:39  <crash-x_> ah thats how you do it
13:31:42  <westbaer> heh
13:31:44  <crash-x_> and about your payload
13:31:57  <crash-x_> does it start a new process like using fork() 
13:32:03  <crash-x_> or does it all the work in the exploited process
13:32:11  <planetbeing> It uses Nucleus-specific calls that create the new task.
13:32:19  <planetbeing> Well, the payload has to create a new task
13:32:22  <westbaer> I think they are documented on the wiki
13:32:25  <planetbeing> To monitor for certain events.
13:32:47  <planetbeing> Yeah, just read Darkmen's decompile.
13:33:00  <planetbeing> us has the exact same payload as ys
13:33:08  <planetbeing> Just different addresses for function calls and stuff.
13:33:19  <planetbeing> And I had to rewrite the loader due to even tighter constraints.
13:33:28  <crash-x_> thats cool, thanks for explaining
13:33:34  <westbaer> yup, thanks

From irc.saurik.com #iphone on Sunday {{date|2009|07|05}}.

Source Code[edit]

The source code [Archived 2011-11-21 at the Wayback Machine] for yellowsn0w 0.9.1 (old version) was released along with yellowsn0w release.

See Also[edit]

External Links[edit]