Support for loading from PayloadFromRPX entrypoint

This commit is contained in:
Maschell 2020-12-04 15:02:37 +01:00
parent 548fab9786
commit a3d477f1a3
9 changed files with 537 additions and 56 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ payload.bin
.idea/ .idea/
cmake-build-debug/ cmake-build-debug/
CMakeLists.txt CMakeLists.txt
payload.elf.bin

View File

@ -17,6 +17,8 @@ export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy export OBJCOPY := $(PREFIX)objcopy
GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# TARGET is the name of the output # TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed # BUILD is the directory where object files & intermediate files will be placed
@ -39,14 +41,14 @@ CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-built
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
-O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) -O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
ASFLAGS := -mregnames ASFLAGS := -mregnames
LDFLAGS := -nostartfiles -Wl,--gc-sections LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition
Q := @ Q := @
MAKEFLAGS += --no-print-directory MAKEFLAGS += --no-print-directory
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := LIBS := -lwut
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
@ -54,7 +56,8 @@ LIBS :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) \ LIBDIRS := $(CURDIR) \
$(DEVKITPPC)/lib \ $(DEVKITPPC)/lib \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 $(DEVKITPRO)/wut \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -10,28 +10,46 @@
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) #define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
typedef struct _private_data_t { typedef struct _private_data_t {
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align); EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx, int size, int align);
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
EXPORT_DECL(void, MEMFreeToDefaultHeap, void *ptr);
EXPORT_DECL(uint64_t, OSGetTitleID);
EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s); EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s);
EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s); EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s);
EXPORT_DECL(void, OSFatal, const char* msg);
EXPORT_DECL(void, OSFatal, const char *msg);
EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*); EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*);
EXPORT_DECL(void, exit, int); EXPORT_DECL(void, exit, int);
EXPORT_DECL(int, FSInit, void); EXPORT_DECL(int, FSInit, void);
EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling);
EXPORT_DECL(int, FSDelClient, void *pClient); EXPORT_DECL(int, FSDelClient, void *pClient);
EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); EXPORT_DECL(void, FSInitCmdBlock, void *pCmd);
EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling);
EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling);
EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling);
EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling);
EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error);
EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling);
EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling);
EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv); EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv);
} private_data_t; } private_data_t;
static void (*DCFlushRange)(void *addr, unsigned int size); static void (*DCFlushRange)(void *addr, unsigned int size);
@ -356,16 +374,16 @@ static int LoadFileToMem(private_data_t *private_data, const char *filepath, uns
int status = private_data->FSGetMountSource(pClient, pCmd, 0, tempPath, -1); int status = private_data->FSGetMountSource(pClient, pCmd, 0, tempPath, -1);
if (status != 0) { if (status != 0) {
private_data->OSFatal("FSGetMountSource failed."); private_data->OSFatal("-13");
} }
status = private_data->FSMount(pClient, pCmd, tempPath, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); status = private_data->FSMount(pClient, pCmd, tempPath, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
if(status != 0) { if(status != 0) {
private_data->OSFatal("SD mount failed."); private_data->OSFatal("-12");
} }
status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1); status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1);
if(status != 0) { if(status != 0) {
private_data->OSFatal("FSOpenFile failed."); private_data->OSFatal("-11");
} }
FSStat stat; FSStat stat;
@ -375,10 +393,11 @@ static int LoadFileToMem(private_data_t *private_data, const char *filepath, uns
private_data->FSGetStatFile(pClient, pCmd, iFd, &stat, -1); private_data->FSGetStatFile(pClient, pCmd, iFd, &stat, -1);
if(stat.size > 0) if (stat.size > 0) {
pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40); pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40);
else } else {
private_data->OSFatal("ELF file empty."); private_data->OSFatal("-10");
}
unsigned int done = 0; unsigned int done = 0;
@ -493,10 +512,11 @@ static void loadFunctionPointers(private_data_t * private_data) {
unsigned int *functionPtr = 0; unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr; private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr; private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr;
OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID);
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal); OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal);
@ -529,12 +549,12 @@ int _start(int argc, char **argv) {
if(MAIN_ENTRY_ADDR != 0xC001C0DE) { if(MAIN_ENTRY_ADDR != 0xC001C0DE) {
loadFunctionPointers(&private_data); loadFunctionPointers(&private_data);
while(1) { while (1) {
if(ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) { if (ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) {
//! copy data to safe area before processing it //! copy data to safe area before processing it
unsigned char * pElfBuffer = (unsigned char *)private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4); unsigned char *pElfBuffer = (unsigned char *) private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4);
if(pElfBuffer) { if (pElfBuffer) {
private_data.memcpy(pElfBuffer, (unsigned char*)ELF_DATA_ADDR, ELF_DATA_SIZE); private_data.memcpy(pElfBuffer, (unsigned char *) ELF_DATA_ADDR, ELF_DATA_SIZE);
MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer);
private_data.MEMFreeToDefaultHeap(pElfBuffer); private_data.MEMFreeToDefaultHeap(pElfBuffer);
@ -543,23 +563,29 @@ int _start(int argc, char **argv) {
ELF_DATA_SIZE = 0; ELF_DATA_SIZE = 0;
} }
if(MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0) { if (MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0) {
//! setup necessary syscalls and hooks for HBL before launching it //! setup necessary syscalls and hooks for HBL before launching it
setup_patches(&private_data); setup_patches(&private_data);
if(HBL_CHANNEL) { if (HBL_CHANNEL) {
break; break;
} else { } else {
unsigned char *pElfBuffer = NULL; unsigned char *pElfBuffer = NULL;
unsigned int uiElfSize = 0; unsigned int uiElfSize = 0;
if (private_data.OSGetTitleID() == 0x000500101004A200L || // mii maker eur
private_data.OSGetTitleID() == 0x000500101004A100L || // mii maker usa
private_data.OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn
LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize); LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize);
}else{
break;
}
if(!pElfBuffer) { if (!pElfBuffer) {
private_data.OSFatal("Failed to load homebrew_launcher.elf"); private_data.OSFatal("Failed to load homebrew_launcher.elf");
} else { } else {
MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer);
if(MAIN_ENTRY_ADDR == 0) { if (MAIN_ENTRY_ADDR == 0) {
private_data.OSFatal("Failed to load homebrew_launcher.elf"); private_data.OSFatal("Failed to load homebrew_launcher.elf");
} else { } else {
private_data.MEMFreeToDefaultHeap(pElfBuffer); private_data.MEMFreeToDefaultHeap(pElfBuffer);
@ -567,12 +593,12 @@ int _start(int argc, char **argv) {
} }
} }
} else { } else {
int returnVal = ((int (*)(int, char **))MAIN_ENTRY_ADDR)(argc, argv); int returnVal = ((int (*)(int, char **)) MAIN_ENTRY_ADDR)(argc, argv);
//! exit to miimaker and restart application on re-enter of another application //! exit to miimaker and restart application on re-enter of another application
if(returnVal == (int)EXIT_RELAUNCH_ON_LOAD) { if (returnVal == (int) EXIT_RELAUNCH_ON_LOAD) {
break; break;
} }
//! exit to homebrew launcher in all other cases //! exit to homebrew launcher in all other cases
else { else {
MAIN_ENTRY_ADDR = 0xDEADC0DE; MAIN_ENTRY_ADDR = 0xDEADC0DE;
private_data.SYSRelaunchTitle(0, 0); private_data.SYSRelaunchTitle(0, 0);

44
src/dynamic.c Normal file
View File

@ -0,0 +1,44 @@
#include <coreinit/dynload.h>
#include <coreinit/debug.h>
#define IMPORT(name) void* addr_##name
#define IMPORT_BEGIN(lib)
#define IMPORT_END()
#include "imports.h"
#undef IMPORT
#undef IMPORT_BEGIN
#undef IMPORT_END
#define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0)
#define IMPORT_BEGIN(lib) OSDynLoad_Acquire(#lib ".rpl", &handle)
/* #define IMPORT_END() OSDynLoad_Release(handle) */
#define IMPORT_END()
#define EXPORT_VAR(type, var) type var __attribute__((section(".data")));
EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap);
EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx);
EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap);
void InitFunctionPointers(void) {
OSDynLoad_Module handle;
addr_OSDynLoad_Acquire = (void *) 0x0102A3B4;
addr_OSDynLoad_FindExport = (void *) 0x0102B828;
OSDynLoad_Acquire("coreinit.rpl", &handle);
uint32_t **value = 0;
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &value);
MEMAllocFromDefaultHeap = *value;
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &value);
MEMAllocFromDefaultHeapEx = *value;
OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &value);
MEMFreeToDefaultHeap = *value;
#include "imports.h"
// override failed __rplwrap_exit find export
OSDynLoad_FindExport(handle, 0, "exit", (void **) &addr___rplwrap_exit);
}

11
src/dynamic.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void InitFunctionPointers(void);
#ifdef __cplusplus
}
#endif

View File

@ -2,6 +2,16 @@
#include "../sd_loader/src/common.h" #include "../sd_loader/src/common.h"
#include "../sd_loader/sd_loader.h" #include "../sd_loader/sd_loader.h"
#include <stdint.h> #include <stdint.h>
#include "dynamic.h"
#include <stdbool.h>
#include <coreinit/thread.h>
#include <sysapp/launch.h>
#include <proc_ui/procui.h>
#include <coreinit/foreground.h>
#include <coreinit/title.h>
#include <sysapp/title.h>
#include <stdio.h>
#include <string.h>
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4) #define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828) #define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
@ -52,16 +62,30 @@ typedef struct _private_data_t {
EXPORT_DECL(int, FSInit, void); EXPORT_DECL(int, FSInit, void);
EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling);
EXPORT_DECL(int, FSDelClient, void *pClient); EXPORT_DECL(int, FSDelClient, void *pClient);
EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); EXPORT_DECL(void, FSInitCmdBlock, void *pCmd);
EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling);
EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling);
EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling);
EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling);
EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error);
EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling);
EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling);
EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv); EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv);
EXPORT_DECL(int, _SYSLaunchMiiStudio);
EXPORT_DECL(int, SYSLaunchMenu);
EXPORT_DECL(uint64_t, OSGetTitleID);
} private_data_t; } private_data_t;
static void InstallPatches(private_data_t *private_data); static void InstallPatches(private_data_t *private_data);
@ -75,10 +99,11 @@ static void loadFunctionPointers(private_data_t * private_data) {
unsigned int *functionPtr = 0; unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr; private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr; private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr;
OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID);
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange); OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange);
@ -102,6 +127,8 @@ static void loadFunctionPointers(private_data_t * private_data) {
unsigned int sysapp_handle; unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle); OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle);
OS_FIND_EXPORT(sysapp_handle, "_SYSLaunchMiiStudio", private_data->_SYSLaunchMiiStudio);
OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu);
} }
static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart) { static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart) {
@ -156,32 +183,50 @@ static unsigned int load_elf_image (private_data_t *private_data, unsigned char
return ehdr->e_entry; return ehdr->e_entry;
} }
void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) { void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) {
pdata->ICInvalidateRange(&value, 4); pdata->ICInvalidateRange(&value, 4);
pdata->DCFlushRange(&value, 4); pdata->DCFlushRange(&value, 4);
uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *)addr); uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *) addr);
uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *)&value); uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *) &value);
SC_0x25_KernelCopyData(dst, src, 4); SC_0x25_KernelCopyData(dst, src, 4);
pdata->DCFlushRange((void *)addr, 4); pdata->DCFlushRange((void *) addr, 4);
pdata->ICInvalidateRange((void *)addr, 4); pdata->ICInvalidateRange((void *) addr, 4);
}
bool CheckRunning() {
switch (ProcUIProcessMessages(true)) {
case PROCUI_STATUS_EXITING: {
return false;
}
case PROCUI_STATUS_RELEASE_FOREGROUND: {
ProcUIDrawDoneRelease();
break;
}
case PROCUI_STATUS_IN_FOREGROUND: {
break;
}
case PROCUI_STATUS_IN_BACKGROUND:
default:
break;
}
return true;
} }
int _start(int argc, char **argv) { int _start(int argc, char **argv) {
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData); 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_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (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_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData); kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int)KernelPatches); kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int)KernelPatches); kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int)KernelPatches); kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int)KernelPatches); kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int)KernelPatches); kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches);
Syscall_0x36(); Syscall_0x36();
@ -190,11 +235,11 @@ int _start(int argc, char **argv) {
InstallPatches(&private_data); InstallPatches(&private_data);
unsigned char * pElfBuffer = (unsigned char *) sd_loader; // use this address as temporary to load the elf unsigned char *pElfBuffer = (unsigned char *) sd_loader; // use this address as temporary to load the elf
unsigned int mainEntryPoint = load_elf_image(&private_data, pElfBuffer); unsigned int mainEntryPoint = load_elf_image(&private_data, pElfBuffer);
if(mainEntryPoint == 0) { if (mainEntryPoint == 0) {
OSFatal("failed to load elf"); OSFatal("failed to load elf");
} }
@ -203,14 +248,41 @@ int _start(int argc, char **argv) {
unsigned int jump_addr = mainEntryPoint & 0x03fffffc; unsigned int jump_addr = mainEntryPoint & 0x03fffffc;
unsigned int bufferU32 = 0x48000003 | jump_addr; unsigned int bufferU32 = 0x48000003 | jump_addr;
KernelWriteU32(repl_addr,bufferU32,&private_data); KernelWriteU32(repl_addr, bufferU32, &private_data);
InitFunctionPointers();
if (
OSGetTitleID() == 0x000500101004A200L || // mii maker eur
OSGetTitleID() == 0x000500101004A100L || // mii maker usa
OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn
// restart mii maker.
private_data.SYSRelaunchTitle(0, 0);
private_data.exit(0);
} else {
ProcUIInit(OSSavesDone_ReadyToRelease);
for (int i = 0; i < argc; i++) {
if(strcmp(argv[i], "void forceDefaultTitleIDToWiiUMenu(void)") == 0){
if((i + 1) < argc){
i++;
void (*forceDefaultTitleIDToWiiUMenu)(void) = (void (*)(void)) argv[i];
forceDefaultTitleIDToWiiUMenu();
}
}
}
SYSLaunchMenu();
while (CheckRunning()) {
// wait.
OSSleepTicks(OSMillisecondsToTicks(100));
}
ProcUIShutdown();
return 0;
}
// restart mii maker.
private_data.SYSRelaunchTitle(0, 0);
private_data.exit(0);
return 0; return 0;
//return ((int (*)(int, char **))mainEntryPoint)(argc, argv);
} }
/* Write a 32-bit word with kernel permissions */ /* Write a 32-bit word with kernel permissions */

24
src/import_stub.S Normal file
View File

@ -0,0 +1,24 @@
/*#define IMPORT(name) \
.global name; \
name: \
lis %r11, addr_##name@h; \
lwz %r11, addr_##name@l(%r11); \
mtctr %r11; \
bctr*/
#define IMPORT(name) \
.global name; \
name: \
lis %r11, addr_##name@h; \
ori %r11, %r11, addr_##name@l; \
lwz %r11, 0(%r11); \
mtctr %r11; \
bctr
#define IMPORT_BEGIN(lib)
#define IMPORT_END()
.align 2;
.section ".text";
#include "imports.h"

294
src/imports.h Normal file
View File

@ -0,0 +1,294 @@
/* coreinit */
IMPORT_BEGIN(coreinit);
IMPORT(OSScreenInit);
IMPORT(OSScreenGetBufferSizeEx);
IMPORT(OSScreenSetBufferEx);
IMPORT(OSScreenEnableEx);
IMPORT(OSScreenFlipBuffersEx);
IMPORT(OSScreenClearBufferEx);
IMPORT(OSScreenPutFontEx);
IMPORT(OSFatal);
IMPORT(OSDynLoad_Acquire);
IMPORT(OSDynLoad_FindExport);
IMPORT(OSDynLoad_Release);
IMPORT(OSSetExceptionCallback);
IMPORT(OSSavesDone_ReadyToRelease);
IMPORT(OSInitMutex);
IMPORT(OSLockMutex);
IMPORT(OSUnlockMutex);
IMPORT(OSInitCond);
IMPORT(OSWaitCond);
IMPORT(OSSignalCond);
IMPORT(OSInitSpinLock);
IMPORT(OSUninterruptibleSpinLock_Acquire);
IMPORT(OSUninterruptibleSpinLock_Release);
IMPORT(OSFastMutex_Init);
IMPORT(OSFastMutex_Lock);
IMPORT(OSFastMutex_Unlock);
IMPORT(OSSleepTicks);
IMPORT(OSGetTitleID);
IMPORT(OSIsThreadTerminated);
IMPORT(OSSetThreadPriority);
IMPORT(OSCreateThread);
IMPORT(OSSetThreadCleanupCallback);
IMPORT(OSResumeThread);
IMPORT(OSIsThreadSuspended);
IMPORT(OSSuspendThread);
IMPORT(OSGetCurrentThread);
IMPORT(OSExitThread);
IMPORT(OSJoinThread);
IMPORT(OSYieldThread);
IMPORT(OSGetCoreId);
IMPORT(OSIsMainCore);
IMPORT(OSGetSystemTime);
IMPORT(OSGetSystemTick);
IMPORT(OSGetTime);
IMPORT(OSGetSymbolName);
IMPORT(OSGetSharedData);
IMPORT(OSEffectiveToPhysical);
IMPORT(OSInitSemaphore);
IMPORT(OSInitSemaphoreEx);
IMPORT(OSGetSemaphoreCount);
IMPORT(OSSignalSemaphore);
IMPORT(OSWaitSemaphore);
IMPORT(OSTryWaitSemaphore);
IMPORT(OSCompareAndSwapAtomicEx);
IMPORT(OSCompareAndSwapAtomic);
IMPORT(OSGetThreadSpecific);
IMPORT(OSSetThreadSpecific);
IMPORT(exit);
IMPORT(_Exit);
IMPORT(__os_snprintf);
IMPORT(DisassemblePPCRange);
IMPORT(ICInvalidateRange);
IMPORT(DCInvalidateRange);
IMPORT(DCFlushRange);
IMPORT(DCStoreRange);
IMPORT(DCStoreRangeNoSync);
IMPORT(__gh_errno_ptr);
IMPORT(MEMGetBaseHeapHandle);
IMPORT(MEMCreateExpHeapEx);
IMPORT(MEMDestroyExpHeap);
IMPORT(MEMAllocFromExpHeapEx);
IMPORT(MEMFreeToExpHeap);
IMPORT(MEMGetSizeForMBlockExpHeap);
IMPORT(MEMAllocFromFrmHeapEx);
IMPORT(MEMFreeToFrmHeap);
IMPORT(MEMGetAllocatableSizeForFrmHeapEx);
IMPORT(FSInit);
IMPORT(FSShutdown);
IMPORT(FSAddClient);
IMPORT(FSAddClientEx);
IMPORT(FSDelClient);
IMPORT(FSInitCmdBlock);
IMPORT(FSChangeDir);
IMPORT(FSGetFreeSpaceSize);
IMPORT(FSGetStat);
IMPORT(FSRemove);
IMPORT(FSOpenFile);
IMPORT(FSCloseFile);
IMPORT(FSOpenDir);
IMPORT(FSMakeDir);
IMPORT(FSReadDir);
IMPORT(FSRewindDir);
IMPORT(FSCloseDir);
IMPORT(FSGetStatFile);
IMPORT(FSReadFile);
IMPORT(FSWriteFile);
IMPORT(FSSetPosFile);
IMPORT(FSFlushFile);
IMPORT(FSTruncateFile);
IMPORT(FSRename);
IMPORT(FSGetMountSource);
IMPORT(FSMount);
IMPORT(FSUnmount);
IMPORT(FSChangeMode);
IMPORT(FSGetPosFile);
IMPORT(OSTicksToCalendarTime);
IMPORT(__rplwrap_exit);
IMPORT(IOS_Open);
IMPORT(IOS_Close);
IMPORT(IOS_Ioctl);
IMPORT(IOS_IoctlAsync);
IMPORT(IMIsAPDEnabled);
IMPORT(IMIsDimEnabled);
IMPORT(IMEnableAPD);
IMPORT(IMEnableDim);
IMPORT(IMDisableAPD);
IMPORT(IMDisableDim);
IMPORT(OSGetSystemInfo);
IMPORT_END();
/* nsysnet */
IMPORT_BEGIN(nsysnet);
IMPORT(socket_lib_init);
IMPORT(getaddrinfo);
IMPORT(freeaddrinfo);
IMPORT(getnameinfo);
IMPORT(inet_ntoa);
IMPORT(inet_ntop);
IMPORT(inet_aton);
IMPORT(inet_pton);
IMPORT(ntohl);
IMPORT(ntohs);
IMPORT(htonl);
IMPORT(htons);
IMPORT(accept);
IMPORT(bind);
IMPORT(socketclose);
IMPORT(connect);
IMPORT(getpeername);
IMPORT(getsockname);
IMPORT(getsockopt);
IMPORT(listen);
IMPORT(recv);
IMPORT(recvfrom);
IMPORT(send);
IMPORT(sendto);
IMPORT(setsockopt);
IMPORT(shutdown);
IMPORT(socket);
IMPORT(select);
IMPORT(socketlasterr);
IMPORT_END();
/* gx2 */
IMPORT_BEGIN(gx2);
IMPORT(GX2Invalidate);
IMPORT(GX2Init);
IMPORT(GX2GetSystemTVScanMode);
IMPORT(GX2CalcTVSize);
IMPORT(GX2SetTVBuffer);
IMPORT(GX2CalcDRCSize);
IMPORT(GX2SetDRCBuffer);
IMPORT(GX2CalcSurfaceSizeAndAlignment);
IMPORT(GX2InitColorBufferRegs);
IMPORT(GX2SetupContextStateEx);
IMPORT(GX2SetContextState);
IMPORT(GX2SetColorBuffer);
IMPORT(GX2SetViewport);
IMPORT(GX2SetScissor);
IMPORT(GX2SetDepthOnlyControl);
IMPORT(GX2SetColorControl);
IMPORT(GX2SetBlendControl);
IMPORT(GX2SetBlendConstantColor);
IMPORT(GX2SetCullOnlyControl);
IMPORT(GX2CalcFetchShaderSizeEx);
IMPORT(GX2InitFetchShaderEx);
IMPORT(GX2SetFetchShader);
IMPORT(GX2SetVertexShader);
IMPORT(GX2SetPixelShader);
IMPORT(GX2SetGeometryShader);
IMPORT(GX2SetGeometryUniformBlock);
IMPORT(GX2SetVertexUniformBlock);
IMPORT(GX2SetPixelUniformBlock);
IMPORT(GX2CalcGeometryShaderInputRingBufferSize);
IMPORT(GX2CalcGeometryShaderOutputRingBufferSize);
IMPORT(GX2SetGeometryShaderInputRingBuffer);
IMPORT(GX2SetGeometryShaderOutputRingBuffer);
IMPORT(GX2SetShaderModeEx);
IMPORT(GX2SetAttribBuffer);
IMPORT(GX2InitTextureRegs);
IMPORT(GX2InitSampler);
IMPORT(GX2SetPixelTexture);
IMPORT(GX2SetPixelSampler);
IMPORT(GX2ClearColor);
IMPORT(GX2CopyColorBufferToScanBuffer);
IMPORT(GX2SwapScanBuffers);
IMPORT(GX2Flush);
IMPORT(GX2WaitForVsync);
IMPORT(GX2SetTVEnable);
IMPORT(GX2SetDRCEnable);
IMPORT(GX2SetSwapInterval);
IMPORT(GX2DrawDone);
IMPORT(GX2Shutdown);
IMPORT(GX2DrawEx);
IMPORT(GX2WaitForFlip);
IMPORT(GX2GetSwapStatus);
IMPORT_END();
/* nn_ac */
IMPORT_BEGIN(nn_ac);
IMPORT(ACInitialize);
IMPORT(ACFinalize);
IMPORT(ACConnect);
IMPORT(ACClose);
IMPORT(ACGetAssignedAddress);
IMPORT(ACGetAssignedSubnet);
IMPORT(Initialize__Q2_2nn3actFv);
IMPORT(GetSlotNo__Q2_2nn3actFv);
IMPORT(GetDefaultAccount__Q2_2nn3actFv);
IMPORT(Finalize__Q2_2nn3actFv);
IMPORT_END();
/* proc_ui */
IMPORT_BEGIN(proc_ui);
IMPORT(ProcUIInit);
IMPORT(ProcUIShutdown);
IMPORT(ProcUIDrawDoneRelease);
IMPORT(ProcUIProcessMessages);
IMPORT_END();
/* sndcore2 */
IMPORT_BEGIN(sndcore2);
IMPORT(AXInitWithParams);
IMPORT(AXQuit);
IMPORT(AXRegisterFrameCallback);
IMPORT(AXAcquireMultiVoice);
IMPORT(AXSetMultiVoiceDeviceMix);
IMPORT(AXSetMultiVoiceOffsets);
IMPORT(AXSetMultiVoiceCurrentOffset);
IMPORT(AXSetMultiVoiceState);
IMPORT(AXSetMultiVoiceVe);
IMPORT(AXSetMultiVoiceSrcType);
IMPORT(AXSetMultiVoiceSrcRatio);
IMPORT(AXIsMultiVoiceRunning);
IMPORT(AXFreeMultiVoice);
IMPORT_END();
/* sysapp */
IMPORT_BEGIN(sysapp);
IMPORT(SYSRelaunchTitle);
IMPORT(_SYSGetSystemApplicationTitleId);
IMPORT(SYSLaunchMenu);
IMPORT(_SYSLaunchMenuWithCheckingAccount);
IMPORT_END();
/* vpad */
IMPORT_BEGIN(vpad);
IMPORT(VPADRead);
IMPORT(VPADInit);
IMPORT(VPADGetTPCalibratedPoint);
IMPORT_END();
/* nsyskbd */
IMPORT_BEGIN(zlib125);
IMPORT(inflateInit_);
IMPORT(inflate);
IMPORT(inflateEnd);
IMPORT_END();

View File

@ -4,14 +4,20 @@ ENTRY(_start);
SECTIONS { SECTIONS {
. = 0x00840000; . = 0x00840000;
.text : { .text : {
*(.kernel_code*);
*(.text*); *(.text*);
} /* Tell linker to not garbage collect this section as it is not referenced anywhere */
KEEP(*(.kernel_code*));
}
.data : { .data : {
*(.rodata*); *(.rodata*);
*(.data*); *(.data*);
*(.sdata*);
*(.bss*); *(.bss*);
*(.sbss*);
} }
__CODE_END = .;
/DISCARD/ : { /DISCARD/ : {
*(*); *(*);
} }