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 (GSM) unlock payload. yellowsn0w was released on New Years Day 2009[1]. ultrasn0w was released on June 23rd 2009[2].
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 Exploit - 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 Baseband's
iPhone 3G/3GS
- 04.26.08
- 05.11.07
- 05.12.01
- 05.13.04
- 06.15.00.
iPhone 4
- 01.59.00
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
Planetbeing explains...
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 the 5th of july.
Source Code
The source code for yellowsn0w 0.9.1 (old version) was released along with yellowsn0w release. [3]