mirror of
https://github.com/wiiu-env/homebrew_launcher_installer.git
synced 2024-11-21 17:59:19 +01:00
Support for loading from PayloadFromRPX entrypoint
This commit is contained in:
parent
548fab9786
commit
a3d477f1a3
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ payload.bin
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
CMakeLists.txt
|
||||
payload.elf.bin
|
||||
|
9
Makefile
9
Makefile
@ -17,6 +17,8 @@ export CXX := $(PREFIX)g++
|
||||
export AR := $(PREFIX)ar
|
||||
export OBJCOPY := $(PREFIX)objcopy
|
||||
|
||||
GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# 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 \
|
||||
-O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
||||
ASFLAGS := -mregnames
|
||||
LDFLAGS := -nostartfiles -Wl,--gc-sections
|
||||
LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition
|
||||
|
||||
Q := @
|
||||
MAKEFLAGS += --no-print-directory
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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
|
||||
@ -54,7 +56,8 @@ LIBS :=
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(CURDIR) \
|
||||
$(DEVKITPPC)/lib \
|
||||
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2
|
||||
$(DEVKITPRO)/wut \
|
||||
$(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
@ -10,28 +10,46 @@
|
||||
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
|
||||
|
||||
typedef struct _private_data_t {
|
||||
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align);
|
||||
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
|
||||
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx, int size, int align);
|
||||
|
||||
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*, 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(void, exit, int);
|
||||
|
||||
EXPORT_DECL(int, FSInit, void);
|
||||
|
||||
EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling);
|
||||
|
||||
EXPORT_DECL(int, FSDelClient, void *pClient);
|
||||
|
||||
EXPORT_DECL(void, FSInitCmdBlock, void *pCmd);
|
||||
|
||||
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, 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, 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, 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
if(status != 0) {
|
||||
private_data->OSFatal("SD mount failed.");
|
||||
private_data->OSFatal("-12");
|
||||
}
|
||||
|
||||
status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1);
|
||||
if(status != 0) {
|
||||
private_data->OSFatal("FSOpenFile failed.");
|
||||
private_data->OSFatal("-11");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(stat.size > 0)
|
||||
if (stat.size > 0) {
|
||||
pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40);
|
||||
else
|
||||
private_data->OSFatal("ELF file empty.");
|
||||
} else {
|
||||
private_data->OSFatal("-10");
|
||||
}
|
||||
|
||||
unsigned int done = 0;
|
||||
|
||||
@ -493,10 +512,11 @@ static void loadFunctionPointers(private_data_t * private_data) {
|
||||
unsigned int *functionPtr = 0;
|
||||
|
||||
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);
|
||||
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, "memset", private_data->memset);
|
||||
OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal);
|
||||
@ -529,12 +549,12 @@ int _start(int argc, char **argv) {
|
||||
if(MAIN_ENTRY_ADDR != 0xC001C0DE) {
|
||||
loadFunctionPointers(&private_data);
|
||||
|
||||
while(1) {
|
||||
if(ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) {
|
||||
while (1) {
|
||||
if (ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) {
|
||||
//! copy data to safe area before processing it
|
||||
unsigned char * pElfBuffer = (unsigned char *)private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4);
|
||||
if(pElfBuffer) {
|
||||
private_data.memcpy(pElfBuffer, (unsigned char*)ELF_DATA_ADDR, ELF_DATA_SIZE);
|
||||
unsigned char *pElfBuffer = (unsigned char *) private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4);
|
||||
if (pElfBuffer) {
|
||||
private_data.memcpy(pElfBuffer, (unsigned char *) ELF_DATA_ADDR, ELF_DATA_SIZE);
|
||||
MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer);
|
||||
private_data.MEMFreeToDefaultHeap(pElfBuffer);
|
||||
|
||||
@ -543,23 +563,29 @@ int _start(int argc, char **argv) {
|
||||
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_patches(&private_data);
|
||||
|
||||
if(HBL_CHANNEL) {
|
||||
if (HBL_CHANNEL) {
|
||||
break;
|
||||
} else {
|
||||
unsigned char *pElfBuffer = NULL;
|
||||
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");
|
||||
} else {
|
||||
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");
|
||||
} else {
|
||||
private_data.MEMFreeToDefaultHeap(pElfBuffer);
|
||||
@ -567,12 +593,12 @@ int _start(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
} 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
|
||||
if(returnVal == (int)EXIT_RELAUNCH_ON_LOAD) {
|
||||
if (returnVal == (int) EXIT_RELAUNCH_ON_LOAD) {
|
||||
break;
|
||||
}
|
||||
//! exit to homebrew launcher in all other cases
|
||||
//! exit to homebrew launcher in all other cases
|
||||
else {
|
||||
MAIN_ENTRY_ADDR = 0xDEADC0DE;
|
||||
private_data.SYSRelaunchTitle(0, 0);
|
||||
|
44
src/dynamic.c
Normal file
44
src/dynamic.c
Normal 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
11
src/dynamic.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void InitFunctionPointers(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
124
src/entry.c
124
src/entry.c
@ -2,6 +2,16 @@
|
||||
#include "../sd_loader/src/common.h"
|
||||
#include "../sd_loader/sd_loader.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_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, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling);
|
||||
EXPORT_DECL(int, FSDelClient, void *pClient);
|
||||
|
||||
EXPORT_DECL(void, FSInitCmdBlock, void *pCmd);
|
||||
|
||||
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, 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, 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, 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;
|
||||
|
||||
static void InstallPatches(private_data_t *private_data);
|
||||
@ -75,10 +99,11 @@ static void loadFunctionPointers(private_data_t * private_data) {
|
||||
unsigned int *functionPtr = 0;
|
||||
|
||||
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);
|
||||
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, "memset", private_data->memset);
|
||||
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;
|
||||
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
|
||||
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) {
|
||||
@ -156,32 +183,50 @@ static unsigned int load_elf_image (private_data_t *private_data, unsigned char
|
||||
return ehdr->e_entry;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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);
|
||||
pdata->DCFlushRange((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) {
|
||||
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);
|
||||
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);
|
||||
|
||||
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_3 + (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_1 + (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_4 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||
|
||||
Syscall_0x36();
|
||||
|
||||
@ -190,11 +235,11 @@ int _start(int argc, char **argv) {
|
||||
|
||||
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);
|
||||
|
||||
if(mainEntryPoint == 0) {
|
||||
if (mainEntryPoint == 0) {
|
||||
OSFatal("failed to load elf");
|
||||
}
|
||||
|
||||
@ -203,14 +248,41 @@ int _start(int argc, char **argv) {
|
||||
unsigned int jump_addr = mainEntryPoint & 0x03fffffc;
|
||||
|
||||
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 ((int (*)(int, char **))mainEntryPoint)(argc, argv);
|
||||
}
|
||||
|
||||
/* Write a 32-bit word with kernel permissions */
|
||||
|
24
src/import_stub.S
Normal file
24
src/import_stub.S
Normal 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
294
src/imports.h
Normal 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();
|
10
src/link.ld
10
src/link.ld
@ -4,14 +4,20 @@ ENTRY(_start);
|
||||
|
||||
SECTIONS {
|
||||
. = 0x00840000;
|
||||
.text : {
|
||||
.text : {
|
||||
*(.kernel_code*);
|
||||
*(.text*);
|
||||
}
|
||||
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
|
||||
KEEP(*(.kernel_code*));
|
||||
}
|
||||
.data : {
|
||||
*(.rodata*);
|
||||
*(.data*);
|
||||
*(.sdata*);
|
||||
*(.bss*);
|
||||
*(.sbss*);
|
||||
}
|
||||
__CODE_END = .;
|
||||
/DISCARD/ : {
|
||||
*(*);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user