|
The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
ultrasn0w
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.
Contents
Credit
MuscleNerd and iPhone 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.
Injection Vectors
- AT+stkprof - used by yellowsn0w to unlock X-Gold 608 baseband 02.28.00.
- AT+XLOG Vulnerability - used by ultrasn0w to unlock X-Gold 608 baseband 04.26.08.
- AT+XAPP Vulnerability - used by ultrasn0w 1.0-1 and 1.2 to unlock public releases of X-Gold 608 basebands 04.26.08 through 05.13.04 and 06.15.00 (ultrasn0w 1.2 only), and XMM 6180 baseband 01.59.00)
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)
Code loader (incl. Stage2)
ROM:00000000 ; =============== S U B R O U T I N E =======================================
ROM:00000000
ROM:00000000
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
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
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
RAM:00011600
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
RAM:40492C20
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:40492C28
RAM:40492C2C
RAM:40492C2C ; =============== S U B R O U T I N E =======================================
RAM:40492C2C
RAM:40492C2C
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
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
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
RAM:00011630
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:00011638
RAM:0001163C
RAM:0001163C ; =============== S U B R O U T I N E =======================================
RAM:0001163C
RAM:0001163C
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
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
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
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 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 stage2 binary and following hexdata are ROM:00000006 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 ROM:00000014 ; ---------------------------------------------------------------------------
Stage2(tm)
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 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 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
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
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 for yellowsn0w 0.9.1 (old version) was released along with yellowsn0w release.