From The Apple Wiki

ultrasn0w (previously: yellowsn0w) is an iPhone 3G, iPhone 3GS and iPhone 4 (iPhone3,1) unlock payload. yellowsn0w was released on New Years Day 2009. ultrasn0w was released on 23 June 2009. 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

Compatible Basebands

iPhone 3G/3GS

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

iPhone 4

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

ultrasn0w payload with comments (by Oranav)

Code loader (incl. Stage2)

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

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!)

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!)

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)

The exploit consists from 4 parts:

Code loader

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

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

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

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

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

External Links