diff --git a/Makefile b/Makefile index 709aaeb..85c5379 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ export OBJCOPY := $(PREFIX)objcopy # SOURCES is a list of directories containing source code # INCLUDES is a list of directories containing extra header files #--------------------------------------------------------------------------------- -TARGET := nanddumper +TARGET := payload BUILD := build BUILD_DBG := $(TARGET)_dbg SOURCES := src \ diff --git a/data/launch_image.tga b/data/launch_image.tga deleted file mode 100644 index 4679174..0000000 Binary files a/data/launch_image.tga and /dev/null differ diff --git a/ios_fs/Makefile b/ios_fs/Makefile index f3c29e6..2969d9f 100644 --- a/ios_fs/Makefile +++ b/ios_fs/Makefile @@ -11,9 +11,8 @@ LINK = arm-none-eabi-gcc AS = arm-none-eabi-as OBJCOPY = arm-none-eabi-objcopy OBJDUMP = arm-none-eabi-objdump -CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os -LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld -LIBDIRS += -L$(CURDIR)/../libs +CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os -fno-tree-loop-distribute-patterns +LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld LIBS += -lgcc CFILES = $(wildcard source/*.c) diff --git a/src/dynamic_libs/os_functions.c b/src/dynamic_libs/os_functions.c index ac4df6f..902d79b 100644 --- a/src/dynamic_libs/os_functions.c +++ b/src/dynamic_libs/os_functions.c @@ -69,6 +69,7 @@ EXPORT_DECL(int, OSTryLockMutex, void* mutex); EXPORT_DECL(u64, OSGetTitleID, void); EXPORT_DECL(void, OSGetArgcArgv, int* argc, char*** argv); EXPORT_DECL(void, __Exit, void); +EXPORT_DECL(void, OSSavesDone_ReadyToRelease, void); EXPORT_DECL(void, OSFatal, const char* msg); EXPORT_DECL(void, OSSetExceptionCallback, u8 exceptionType, exception_callback newCallback); EXPORT_DECL(void, DCFlushRange, const void *addr, u32 length); @@ -121,8 +122,8 @@ void InitAcquireOS(void) //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Lib handle functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire); - EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport); + EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))0x0102A3B4); + EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))0x0102B828); OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); } @@ -144,6 +145,7 @@ void InitOSFunctionPointers(void) OS_FIND_EXPORT(coreinit_handle, OSFatal); OS_FIND_EXPORT(coreinit_handle, OSGetTitleID); OS_FIND_EXPORT(coreinit_handle, OSGetArgcArgv); + OS_FIND_EXPORT(coreinit_handle, OSSavesDone_ReadyToRelease); OS_FIND_EXPORT(coreinit_handle, OSSetExceptionCallback); OS_FIND_EXPORT(coreinit_handle, DCFlushRange); OS_FIND_EXPORT(coreinit_handle, DCStoreRange); diff --git a/src/dynamic_libs/os_functions.h b/src/dynamic_libs/os_functions.h index 0dc7c52..63e6519 100644 --- a/src/dynamic_libs/os_functions.h +++ b/src/dynamic_libs/os_functions.h @@ -111,6 +111,7 @@ extern int (* OSTryLockMutex)(void* mutex); extern u64 (* OSGetTitleID)(void); extern void (* OSGetArgcArgv)(int* argc, char*** argv); extern void (* __Exit)(void); +extern void (* OSSavesDone_ReadyToRelease)(void); extern void (* OSFatal)(const char* msg); extern void (* DCFlushRange)(const void *addr, u32 length); extern void (* DCStoreRange)(const void *addr, u32 length); diff --git a/src/dynamic_libs/proc_ui_functions.c b/src/dynamic_libs/proc_ui_functions.c new file mode 100644 index 0000000..479aa51 --- /dev/null +++ b/src/dynamic_libs/proc_ui_functions.c @@ -0,0 +1,54 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#include "os_functions.h" +#include "proc_ui_functions.h" + +u32 proc_ui_handle __attribute__((section(".data"))) = 0; + +EXPORT_DECL(void, ProcUIInit, ProcUISaveCallback saveCallback); +EXPORT_DECL(void, ProcUIShutdown); +EXPORT_DECL(void, ProcUIDrawDoneRelease); + +EXPORT_DECL(ProcUIStatus, ProcUIProcessMessages, BOOL block); +EXPORT_DECL(u32, ProcUIInForeground, void); +EXPORT_DECL(void, ProcUIRegisterCallback, u32 type,ProcUICallback callback,void* param, u32 unkwn); + +void InitAcquireProcUI(void) { + if(coreinit_handle == 0) { + InitAcquireOS(); + }; + OSDynLoad_Acquire("proc_ui.rpl", &proc_ui_handle); +} + +void InitProcUIFunctionPointers(void) { + u32 *funcPointer = 0; + InitAcquireProcUI(); + + OS_FIND_EXPORT(proc_ui_handle, ProcUIInForeground); + OS_FIND_EXPORT(proc_ui_handle, ProcUIRegisterCallback); + OS_FIND_EXPORT(proc_ui_handle, ProcUIInit); + OS_FIND_EXPORT(proc_ui_handle, ProcUIDrawDoneRelease); + OS_FIND_EXPORT(proc_ui_handle, ProcUIProcessMessages); + OS_FIND_EXPORT(proc_ui_handle, ProcUIShutdown); +} diff --git a/src/dynamic_libs/proc_ui_functions.h b/src/dynamic_libs/proc_ui_functions.h new file mode 100644 index 0000000..c9a37c2 --- /dev/null +++ b/src/dynamic_libs/proc_ui_functions.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * Copyright (C) 2015 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef __PROC_UI_FUNCTIONS_H_ +#define __PROC_UI_FUNCTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os_types.h" + +extern u32 proc_ui_handle; + +typedef u32 (*ProcUICallback)(void*); +typedef void (*ProcUISaveCallback)(void); + +typedef enum ProcUIStatus +{ + //! The application is in the foreground. All resources may be used. + PROCUI_STATUS_IN_FOREGROUND, + //! The application is in the background, only limited resources are usable. + PROCUI_STATUS_IN_BACKGROUND, + //! The application must release the foregound - see ProcUIDrawDoneRelease() + PROCUI_STATUS_RELEASE_FOREGROUND, + //! The application must release all resources (including ProcUI) and quit + PROCUI_STATUS_EXITING, +} ProcUIStatus; + +void InitProcUIFunctionPointers(void); +void InitAcquireProcUI(void); + +extern void (*ProcUIInit)(ProcUISaveCallback saveCallback); +extern void (*ProcUIDrawDoneRelease)(); +extern void (*ProcUIShutdown)(); + +extern ProcUIStatus (*ProcUIProcessMessages)(BOOL block); + +extern u32 (*ProcUIInForeground)(void); +extern void (*ProcUIRegisterCallback)(u32 type,ProcUICallback callback,void* param, u32 unkwn); + +#ifdef __cplusplus +} +#endif + +#endif // __PROC_UI_FUNCTIONS_H_ diff --git a/src/dynamic_libs/socket_functions.h b/src/dynamic_libs/socket_functions.h index 1e4df1a..f87678f 100644 --- a/src/dynamic_libs/socket_functions.h +++ b/src/dynamic_libs/socket_functions.h @@ -33,6 +33,7 @@ extern unsigned int nsysnet_handle; #include #define INADDR_ANY 0 +#define INADDR_BROADCAST 0xFFFFFFFF #define AF_INET 2 @@ -47,6 +48,7 @@ extern unsigned int nsysnet_handle; #define SOL_SOCKET -1 #define SO_REUSEADDR 0x0004 +#define SO_BROADCAST 0x0020 // broadcast #define SO_NONBLOCK 0x1016 #define SO_MYADDR 0x1013 #define SO_RCVTIMEO 0x1006 diff --git a/src/entry.c b/src/entry.c index 759cee0..cb62803 100644 --- a/src/entry.c +++ b/src/entry.c @@ -1,14 +1,140 @@ #include -#include "dynamic_libs/os_functions.h" -#include "dynamic_libs/sys_functions.h" -#include "common/common.h" -#include "utils/utils.h" -#include "main.h" +#include +#include +#include +#include +#include +#include -int __entry_menu(int argc, char **argv) -{ - //! ******************************************************************* - //! * Jump to our application * - //! ******************************************************************* +#include "main.h" +#include "ios_exploit.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) +#define OSFatal ((void (*)(char* msg))0x01031618) + +#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__); +#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) + +#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040 +#define ADDRESS_main_entry_hook 0x0101c56c + +#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown +#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games +#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader +#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu +#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) + +/* assembly functions */ +extern void Syscall_0x36(void); +extern void KernelPatches(void); +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); + +void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); + +typedef struct _private_data_t { + EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align); + EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr); + + 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(unsigned int, OSEffectiveToPhysical, const void*); + EXPORT_DECL(void, exit, int); + EXPORT_DECL(void, DCInvalidateRange, const void *addr, unsigned int length); + EXPORT_DECL(void, DCFlushRange, const void *addr, unsigned int length); + EXPORT_DECL(void, ICInvalidateRange, const void *addr, unsigned int length); + EXPORT_DECL(void, OSForceFullRelaunch); + + EXPORT_DECL(void, SYSRelaunchTitle, int argc, char** argv); + EXPORT_DECL(void, SYSLaunchMenu); +} private_data_t; + + +static 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, "OSForceFullRelaunch", private_data->OSForceFullRelaunch); + OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit); + + 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); +} + +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); +} + +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 + (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(); + + private_data_t private_data; + loadFunctionPointers(&private_data); + + unsigned int repl_addr = ADDRESS_main_entry_hook; + unsigned int bufferU32 = 0x4E800421; + KernelWriteU32(repl_addr,bufferU32,&private_data); + return Menu_Main(); } + +/* 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" + ); +} \ No newline at end of file diff --git a/src/ios_exploit.c b/src/ios_exploit.c index 051869b..f457945 100644 --- a/src/ios_exploit.c +++ b/src/ios_exploit.c @@ -13,9 +13,6 @@ #define ARM_CODE_BASE 0x08135000 #define REPLACE_SYSCALL 0x081298BC -extern const u8 launch_image_tga[]; -extern const u32 launch_image_tga_size; - static void uhs_exploit_init(int uhs_handle, cfw_config_t * config); static int uhs_write32(int uhs_handle, int arm_addr, int val); diff --git a/src/kernel_asm.S b/src/kernel_asm.S new file mode 100644 index 0000000..3edc393 --- /dev/null +++ b/src/kernel_asm.S @@ -0,0 +1,239 @@ +.section ".kernel_code" + .globl SaveAndResetDataBATs_And_SRs_hook +SaveAndResetDataBATs_And_SRs_hook: + # setup CTR to the position we need to return to + mflr r5 + mtctr r5 + # set link register to its original value + mtlr r7 + # setup us a nice DBAT for our code data with same region as our code + mfspr r5, 560 + mtspr 570, r5 + mfspr r5, 561 + mtspr 571, r5 + # restore the original kernel instructions that we replaced + lwz r5, 0x34(r3) + lwz r6, 0x38(r3) + lwz r7, 0x3C(r3) + lwz r8, 0x40(r3) + lwz r9, 0x44(r3) + lwz r10, 0x48(r3) + lwz r11, 0x4C(r3) + lwz r3, 0x50(r3) + isync + mtsr 7, r5 + # jump back to the position in kernel after our patch (from LR) + bctr + + +#define BAT_SETUP_HOOK_ADDR 0xFFF1D624 +# not all of those NOP address are required for every firmware +# mainly these should stop the kernel from removing our IBAT4 and DBAT5 +#define BAT_SET_NOP_ADDR_1 0xFFF06B6C +#define BAT_SET_NOP_ADDR_2 0xFFF06BF8 +#define BAT_SET_NOP_ADDR_3 0xFFF003C8 +#define BAT_SET_NOP_ADDR_4 0xFFF003CC +#define BAT_SET_NOP_ADDR_5 0xFFF1D70C +#define BAT_SET_NOP_ADDR_6 0xFFF1D728 +#define BAT_SET_NOP_ADDR_7 0xFFF1D82C + +#define BAT_SET_NOP_ADDR_8 0xFFEE11C4 +#define BAT_SET_NOP_ADDR_9 0xFFEE11C8 + +#define BAT_SETUP_HOOK_ENTRY 0x00800000 + + +#define BAT4U_VAL 0x008000FF +#define BAT4L_VAL 0x30800012 + + +#define SET_R4_TO_ADDR(addr) \ + lis r3, addr@h ; \ + ori r3, r3, addr@l ; \ + stw r4, 0(r3) ; \ + dcbf 0, r3 ; \ + icbi 0, r3 ; + + .globl Syscall_0x36 +Syscall_0x36: + li r0, 0x3600 + sc + blr + + +.global SCKernelCopyData +SCKernelCopyData: + // Disable data address translation + mfmsr %r6 + li %r7, 0x10 + andc %r6, %r6, %r7 + mtmsr %r6 + + // Copy data + addi %r3, %r3, -1 + addi %r4, %r4, -1 + mtctr %r5 +SCKernelCopyData_loop: + lbzu %r5, 1(%r4) + stbu %r5, 1(%r3) + bdnz SCKernelCopyData_loop + + // Enable data address translation + ori %r6, %r6, 0x10 + mtmsr %r6 +blr + +.global SC_0x25_KernelCopyData +SC_0x25_KernelCopyData: + li %r0, 0x2500 + sc +blr + + .globl KernelPatches +KernelPatches: + # store the old DBAT0 + mfdbatu r5, 0 + mfdbatl r6, 0 + + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFF0 + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFF0 + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though + # just chosen because its simple + lis r3, BAT_SETUP_HOOK_ADDR@h + ori r3, r3, BAT_SETUP_HOOK_ADDR@l + + # make the kernel setup our section in IBAT4 and + # jump to our function to restore the replaced instructions + lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h + ori r4, r4, BAT4L_VAL@h + stw r4, 0x00(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l + ori r4, r4, BAT4L_VAL@l + stw r4, 0x04(r3) + lis r4, 0x7cf1 # mtspr 561, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x08(r3) + lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h + ori r4, r4, BAT4U_VAL@h + stw r4, 0x0C(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l + ori r4, r4, BAT4U_VAL@l + stw r4, 0x10(r3) + lis r4, 0x7cf0 # mtspr 560, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x14(r3) + lis r4, 0x7c00 # eieio + ori r4, r4, 0x06ac + stw r4, 0x18(r3) + lis r4, 0x4c00 # isync + ori r4, r4, 0x012c + stw r4, 0x1C(r3) + lis r4, 0x7ce8 # mflr r7 + ori r4, r4, 0x02a6 + stw r4, 0x20(r3) + lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY + ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l + stw r4, 0x24(r3) + + # flush and invalidate the replaced instructions + lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h + ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l + dcbf 0, r3 + icbi 0, r3 + lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h + ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l + dcbf 0, r3 + icbi 0, r3 + sync + + # setup IBAT4 for core 1 at this position (not really required but wont hurt) + # IBATL 4 + lis r3, BAT4L_VAL@h + ori r3, r3, BAT4L_VAL@l + mtspr 561, r3 + + # IBATU 4 + lis r3, BAT4U_VAL@h + ori r3, r3, BAT4U_VAL@l + mtspr 560, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + # nop on IBATU 4 and DBAT 5 set/reset +#ifdef BAT_SET_NOP_ADDR_1 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1) +#endif +#ifdef BAT_SET_NOP_ADDR_2 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2) +#endif +#ifdef BAT_SET_NOP_ADDR_3 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3) +#endif +#ifdef BAT_SET_NOP_ADDR_4 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4) +#endif +#ifdef BAT_SET_NOP_ADDR_5 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5) +#endif +#ifdef BAT_SET_NOP_ADDR_6 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6) +#endif +#ifdef BAT_SET_NOP_ADDR_7 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7) +#endif + +#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9)) + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFEE + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFEE + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8) + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9) +#endif + + # memory barrier + eieio + isync + + # restore DBAT 0 and return from interrupt + mtdbatu 0, r5 + mtdbatl 0, r6 + + # memory barrier + eieio + isync + + blr + diff --git a/src/link.ld b/src/link.ld index fc569d1..80ab938 100644 --- a/src/link.ld +++ b/src/link.ld @@ -1,40 +1,25 @@ -OUTPUT(ftpiiu.elf); +OUTPUT(payload.elf); -/* Tell linker where our application entry is so the garbage collect can work correct */ -ENTRY(__entry_menu); +ENTRY(_start); SECTIONS { - . = 0x00802000; + . = 0x00840000; .text : { + *(.kernel_code*); *(.text*); - } - .rodata : { - *(.rodata*); - } + /* Tell linker to not garbage collect this section as it is not referenced anywhere */ + KEEP(*(.kernel_code*)); + } .data : { - *(.data*); - - __sdata_start = .; + *(.rodata*); *(.sdata*); - __sdata_end = .; - - __sdata2_start = .; - *(.sdata2*); - __sdata2_end = .; - } - .bss : { - __bss_start = .; + *(.data*); *(.bss*); *(.sbss*); - *(COMMON); - __bss_end = .; } - __CODE_END = .; - /DISCARD/ : { *(*); } } -/******************************************************** FS ********************************************************/ -/* coreinit.rpl difference in addresses 0xFE3C00 */ +ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x7C0000, "elf is too big"); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 2fab0ea..71e6955 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/socket_functions.h" +#include "dynamic_libs/proc_ui_functions.h" #include "fs/fs_utils.h" #include "fs/sd_fat_devoptab.h" #include "system/memory.h" @@ -23,6 +24,27 @@ static int exitToHBLOnLaunch = 0; +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 Menu_Main(void) { //!---------INIT--------- @@ -31,22 +53,10 @@ int Menu_Main(void) InitFSFunctionPointers(); InitSocketFunctionPointers(); InitVPadFunctionPointers(); + InitProcUIFunctionPointers(); u64 currenTitleId = OSGetTitleID(); - // in case we are not in mii maker or HBL channel but in system menu or another channel we need to exit here - if (currenTitleId != 0x000500101004A200 && // mii maker eur - currenTitleId != 0x000500101004A100 && // mii maker usa - currenTitleId != 0x000500101004A000 && // mii maker jpn - currenTitleId != 0x0005000013374842) // HBL channel - { - return EXIT_RELAUNCH_ON_LOAD; - } - else if(exitToHBLOnLaunch) - { - return 0; - } - VPADInit(); /*int forceMenu = 0; @@ -73,30 +83,32 @@ int Menu_Main(void) //{ launch = ShowMenu(&config); //} + + ExecuteIOSExploit(&config); + if ( + OSGetTitleID() == 0x000500101004A200L || // mii maker eur + OSGetTitleID() == 0x000500101004A100L || // mii maker usa + OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn - int returnCode = 0; + // restart mii maker. + OSForceFullRelaunch(); + SYSLaunchMenu(); + exit(0); + } else { + ProcUIInit(OSSavesDone_ReadyToRelease); + + OSForceFullRelaunch(); + SYSLaunchMenu(); - if(launch) - { - int res = ExecuteIOSExploit(&config); - if(res == 0) - { - //if(config.noIosReload == 0) - //{ - OSForceFullRelaunch(); - SYSLaunchMenu(); - returnCode = EXIT_RELAUNCH_ON_LOAD; - //} - //else if(config.launchSysMenu) - //{ - // SYSLaunchMenu(); - // exitToHBLOnLaunch = 1; - // returnCode = EXIT_RELAUNCH_ON_LOAD; - //} + while (CheckRunning()) { + // wait. + OSSleepTicks(MILLISECS_TO_TICKS(100)); } + ProcUIShutdown(); + + return 0; } - //unmount_sd_fat("sd"); - return returnCode; + return 0; } diff --git a/src/utils/logger.c b/src/utils/logger.c index f4795b4..a3b4688 100644 --- a/src/utils/logger.c +++ b/src/utils/logger.c @@ -3,60 +3,46 @@ #include #include #include -#include "common/common.h" -#include "dynamic_libs/os_functions.h" -#include "dynamic_libs/socket_functions.h" #include "logger.h" +#include +#include -#ifdef DEBUG_LOGGER -static int log_socket = -1; -static volatile int log_lock = 0; +static int log_socket __attribute__((section(".data")))= -1; +static struct sockaddr_in connect_addr __attribute__((section(".data"))); +static volatile int log_lock __attribute__((section(".data"))) = 0; +void log_init_() { + InitOSFunctionPointers(); + InitSocketFunctionPointers(); -void log_init(const char * ipString) -{ - log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (log_socket < 0) - return; + int broadcastEnable = 1; + log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (log_socket < 0) + return; - struct sockaddr_in connect_addr; - memset(&connect_addr, 0, sizeof(connect_addr)); - connect_addr.sin_family = AF_INET; - connect_addr.sin_port = 4405; - inet_aton(ipString, &connect_addr.sin_addr); + setsockopt(log_socket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)); - if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) - { - socketclose(log_socket); - log_socket = -1; - } + memset(&connect_addr, 0, sizeof(struct sockaddr_in)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = 4405; + connect_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); } -void log_deinit(void) -{ - if(log_socket >= 0) - { - socketclose(log_socket); - log_socket = -1; - } -} - -void log_print(const char *str) -{ +void log_print_(const char *str) { // socket is always 0 initially as it is in the BSS if(log_socket < 0) { return; } while(log_lock) - usleep(1000); + os_usleep(1000); log_lock = 1; int len = strlen(str); int ret; while (len > 0) { int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet - ret = send(log_socket, str, block, 0); + ret = sendto(log_socket, str, block, 0, (struct sockaddr *)&connect_addr, sizeof(struct sockaddr_in)); if(ret < 0) break; @@ -67,23 +53,32 @@ void log_print(const char *str) log_lock = 0; } -void log_printf(const char *format, ...) -{ +void OSFatal_printf(const char *format, ...) { + char * tmp = NULL; + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) { + OSFatal(tmp); + } + va_end(va); +} + +void log_printf_(const char *format, ...) { if(log_socket < 0) { return; } - char * tmp = NULL; - va_list va; - va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) - { - log_print(tmp); - } - va_end(va); + char * tmp = NULL; - if(tmp) - free(tmp); + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) { + log_print_(tmp); + } + va_end(va); + + if(tmp) + free(tmp); } -#endif + diff --git a/src/utils/logger.h b/src/utils/logger.h index dd7cc71..32e65b8 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -5,19 +5,42 @@ extern "C" { #endif -#define DEBUG_LOGGER 1 +#include + +void log_init_(); +//void log_deinit_(void); +void log_print_(const char *str); +void log_printf_(const char *format, ...); +void OSFatal_printf(const char *format, ...); + +#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) + +#define OSFATAL_FUNCTION_LINE(FMT, ARGS...)do { \ + OSFatal_printf("[%s]%s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + } while (0) + +#ifdef __LOGGING__ + +#define log_init() log_init_() +//#define log_deinit() log_deinit_() +#define log_print(str) log_print_(str) +#define log_printf(FMT, ARGS...) log_printf_(FMT, ## ARGS); + +#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ + log_printf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + } while (0) + -#ifdef DEBUG_LOGGER -void log_init(const char * ip); -void log_deinit(void); -void log_print(const char *str); -void log_printf(const char *format, ...); #else -#define log_init(x) -#define log_deinit() + +#define log_init() +//#define log_deinit() #define log_print(x) #define log_printf(x, ...) -#endif +#define DEBUG_FUNCTION_LINE(FMT, ARGS...) + +#endif //__LOGGING__ #ifdef __cplusplus }