payload_loader/src/utils.c

168 lines
7.0 KiB
C

#include "utils.h"
extern void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
extern void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
static void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) {
pdata->ICInvalidateRange(&value, 4);
pdata->DCFlushRange(&value, 4);
uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *)addr);
uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *)&value);
SC_0x25_KernelCopyData(dst, src, 4);
pdata->DCFlushRange((void *)addr, 4);
pdata->ICInvalidateRange((void *)addr, 4);
}
void revertMainHook(private_data_t * private_data) {
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
unsigned int repl_addr = ADDRESS_main_entry_hook;
unsigned int bufferU32 = 0x4E800421;
KernelWriteU32(repl_addr,bufferU32,private_data);
}
void PrepareScreen(private_data_t *private_data) {
// Prepare screen
int screen_buf0_size = 0;
int screen_buf1_size = 0;
unsigned int screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a;
// Init screen and screen buffers
private_data->OSScreenInit();
screen_buf0_size = private_data->OSScreenGetBufferSizeEx(0);
screen_buf1_size = private_data->OSScreenGetBufferSizeEx(1);
private_data->OSScreenSetBufferEx(0, (void *)0xF4000000);
private_data->OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
// Clear screens
private_data->OSScreenClearBufferEx(0, screen_color);
private_data->OSScreenClearBufferEx(1, screen_color);
// Flush the cache
private_data->DCFlushRange((void *)0xF4000000, screen_buf0_size);
private_data->DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
// Flip buffers
private_data->OSScreenFlipBuffersEx(0);
private_data->OSScreenFlipBuffersEx(1);
}
void ExitFailure(private_data_t *private_data, const char *failure) {
PrepareScreen(private_data);
private_data->OSScreenClearBufferEx(1,0);
private_data->OSScreenPutFontEx(1, 0, 0, failure);
private_data->OSScreenFlipBuffersEx(1);
private_data->OSScreenClearBufferEx(1,0);
private_data->OSScreenPutFontEx(1, 0, 0, failure);
private_data->OSScreenFlipBuffersEx(1);
}
void loadFunctionPointers(private_data_t * private_data) {
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit", &coreinit_handle);
unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr;
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange);
OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", private_data->DCInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", private_data->ICInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "OSEffectiveToPhysical", private_data->OSEffectiveToPhysical);
OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit);
OS_FIND_EXPORT(coreinit_handle, "FSInit", private_data->FSInit);
OS_FIND_EXPORT(coreinit_handle, "FSAddClientEx", private_data->FSAddClientEx);
OS_FIND_EXPORT(coreinit_handle, "FSDelClient", private_data->FSDelClient);
OS_FIND_EXPORT(coreinit_handle, "FSInitCmdBlock", private_data->FSInitCmdBlock);
OS_FIND_EXPORT(coreinit_handle, "FSGetMountSource", private_data->FSGetMountSource);
OS_FIND_EXPORT(coreinit_handle, "FSMount", private_data->FSMount);
OS_FIND_EXPORT(coreinit_handle, "FSUnmount", private_data->FSUnmount);
OS_FIND_EXPORT(coreinit_handle, "FSOpenFile", private_data->FSOpenFile);
OS_FIND_EXPORT(coreinit_handle, "FSGetStatFile", private_data->FSGetStatFile);
OS_FIND_EXPORT(coreinit_handle, "FSReadFile", private_data->FSReadFile);
OS_FIND_EXPORT(coreinit_handle, "FSCloseFile", private_data->FSCloseFile);
OS_FIND_EXPORT(coreinit_handle, "OSSleepTicks", private_data->OSSleepTicks);
OS_FIND_EXPORT(coreinit_handle, "OSScreenPutFontEx", private_data->OSScreenPutFontEx);
OS_FIND_EXPORT(coreinit_handle, "OSScreenInit", private_data->OSScreenInit);
OS_FIND_EXPORT(coreinit_handle, "OSScreenGetBufferSizeEx", private_data->OSScreenGetBufferSizeEx);
OS_FIND_EXPORT(coreinit_handle, "OSScreenSetBufferEx", private_data->OSScreenSetBufferEx);
OS_FIND_EXPORT(coreinit_handle, "OSScreenClearBufferEx", private_data->OSScreenClearBufferEx);
OS_FIND_EXPORT(coreinit_handle, "OSScreenFlipBuffersEx", private_data->OSScreenFlipBuffersEx);
OS_FIND_EXPORT(coreinit_handle, "OSForceFullRelaunch", private_data->OSForceFullRelaunch);
unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle);
OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu);
OS_FIND_EXPORT(sysapp_handle, "_SYSLaunchMiiStudio", private_data->_SYSLaunchMiiStudio);
OS_FIND_EXPORT(sysapp_handle, "_SYSGetSystemApplicationTitleId", private_data->_SYSGetSystemApplicationTitleId);
OS_FIND_EXPORT(sysapp_handle, "_SYSLaunchTitleWithStdArgsInNoSplash", private_data->_SYSLaunchTitleWithStdArgsInNoSplash);
private_data->sysmenuTitleID = private_data->_SYSGetSystemApplicationTitleId(0);
}
/* Read a 32-bit word with kernel permissions */
uint32_t __attribute__ ((noinline)) kern_read(const void *addr) {
uint32_t result;
asm volatile (
"li 3,1\n"
"li 4,0\n"
"li 5,0\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%1\n"
"li 0,0x3400\n"
"mr %0,1\n"
"sc\n"
"nop\n"
"mr 1,%0\n"
"mr %0,3\n"
: "=r"(result)
: "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
return result;
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}