diff --git a/.gitignore b/.gitignore index fc4a5a8..919e10f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,9 @@ /ios_usb/ios_usb.bin.h /ios_usb/*.elf /ios_usb/ios_usb_syms.h -/ios_usb/build \ No newline at end of file +/ios_usb/build +/ios_acp/build +/ios_acp/*.bin +/ios_acp/ios_acp.bin.h +/ios_acp/*.elf +/ios_acp/ios_acp_syms.h diff --git a/Makefile b/Makefile index 75eb747..fb9430e 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ $(BUILD): $(CURDIR)/ios_kernel/ios_kernel.bin.h @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile -$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_fs/ios_fs.bin.h $(CURDIR)/ios_bsp/ios_bsp.bin.h +$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_fs/ios_fs.bin.h $(CURDIR)/ios_bsp/ios_bsp.bin.h $(CURDIR)/ios_acp/ios_acp.bin.h @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile $(CURDIR)/ios_usb/ios_usb.bin.h: @@ -137,6 +137,9 @@ $(CURDIR)/ios_bsp/ios_bsp.bin.h: $(CURDIR)/ios_mcp/ios_mcp.bin.h: @$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile + +$(CURDIR)/ios_acp/ios_acp.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile #--------------------------------------------------------------------------------- clean: @@ -147,6 +150,7 @@ clean: @$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile clean #--------------------------------------------------------------------------------- diff --git a/common/config_types.h b/common/config_types.h new file mode 100644 index 0000000..abe9154 --- /dev/null +++ b/common/config_types.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 _CONFIG_TYPES_H_ +#define _CONFIG_TYPES_H_ + +typedef struct +{ + int viewMode; + int directLaunch; + int launchImage; + int noIosReload; + int launchSysMenu; + int redNAND; + int seeprom_red; + int otp_red; + int syshaxXml; +} cfw_config_t; + +#endif diff --git a/common/kernel_commands.h b/common/kernel_commands.h new file mode 100644 index 0000000..1f27b53 --- /dev/null +++ b/common/kernel_commands.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 KERNEL_COMMANDS_H_ +#define KERNEL_COMMANDS_H_ + +#define KERNEL_READ32 1 +#define KERNEL_WRITE32 2 +#define KERNEL_MEMCPY 3 +#define KERNEL_GET_CFW_CONFIG 4 + +#endif diff --git a/ios_acp/Makefile b/ios_acp/Makefile new file mode 100644 index 0000000..eaa8bc0 --- /dev/null +++ b/ios_acp/Makefile @@ -0,0 +1,80 @@ +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) +export PATH:=$(DEVKITARM)/bin:$(PATH) +endif + +CC = arm-none-eabi-gcc +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 +LIBS += -lgcc + +CFILES = $(wildcard source/*.c) +BINFILES = $(wildcard data/*.bin) +OFILES = $(BINFILES:data/%.bin=build/%.bin.o) +OFILES += $(CFILES:source/%.c=build/%.o) +DFILES = $(CFILES:source/%.c=build/%.d) +SFILES = $(wildcard source/*.s) +OFILES += $(SFILES:source/%.s=build/%.o) +PROJECTNAME = ${shell basename "$(CURDIR)"} +CWD = "$(CURDIR)"" + +#--------------------------------------------------------------------------------- +# canned command sequence for binary data, taken from devkitARM +#--------------------------------------------------------------------------------- +define bin2o + bin2s $< | $(AS) -EB -o $(@) +endef + +.PHONY:=all dirs + +all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + +dirs: + @mkdir -p build + +$(PROJECTNAME).elf: $(OFILES) + @echo "LD $@" + @$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS) + +$(PROJECTNAME).bin: $(PROJECTNAME).elf + @echo "OBJCOPY $@\n" + @$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@ + +$(PROJECTNAME).bin.h: $(PROJECTNAME).bin + @xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@ + +$(PROJECTNAME)_syms.h: + @echo "#ifndef $(PROJECTNAME)_SYMS_H" > $@ + @echo "#define $(PROJECTNAME)_SYMS_H" >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' -e "_seeprom_buffer_start" | awk '{print "#define " $$5 " 0x" $$1}' >> $@ + @echo "#endif" >> $@ + +clean: + @rm -f build/*.o build/*.d + @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + @echo "all cleaned up !" + +-include $(DFILES) + +build/%.o: source/%.c + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.o: source/%.s + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo "BIN $(notdir $<)" + @$(bin2o) diff --git a/ios_acp/link.ld b/ios_acp/link.ld new file mode 100644 index 0000000..826cf00 --- /dev/null +++ b/ios_acp/link.ld @@ -0,0 +1,23 @@ +OUTPUT_ARCH(arm) + +SECTIONS +{ + .text 0xE00DB660 : { + _text_start = .; + *(.text*); + *(.rodata*); + } + _text_end = .; + + .bss 0xE0261F10 : { + _bss_start = .; + *(.bss*); + *(.data*); + } + _bss_end = .; + + /DISCARD/ : { + *(*); + } +} + diff --git a/ios_acp/source/imports.h b/ios_acp/source/imports.h new file mode 100644 index 0000000..229134c --- /dev/null +++ b/ios_acp/source/imports.h @@ -0,0 +1,7 @@ +#ifndef _IMPORTS_H_ +#define _IMPORTS_H_ + +#define ACP_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0xE00C4D54) + + +#endif diff --git a/ios_acp/source/main.c b/ios_acp/source/main.c new file mode 100644 index 0000000..bf081e2 --- /dev/null +++ b/ios_acp/source/main.c @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 "types.h" + +int ACP_FSARawRead_hook(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle) +{ + int (*ACP_FSARawRead)(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle) = (void*)0xE00BAF74; + + int res = ACP_FSARawRead(fd, data, offset, cnt, blocksize, device_handle); + + //! the PPC side has a way to check for a PC or WFS formatted drive by checking the MBR signature + //! it's the only place where this is used so we can just fake it with wrong values. + u8 *buf = (u8*)data; + if((offset == 0) && (buf[510] == 0x55) && (buf[511] == 0xAA)) + { + buf[510] = 0xB3; + buf[511] = 0xDE; + } + return res; +} diff --git a/ios_acp/source/types.h b/ios_acp/source/types.h new file mode 100644 index 0000000..832bc29 --- /dev/null +++ b/ios_acp/source/types.h @@ -0,0 +1,29 @@ +#ifndef TYPES_H +#define TYPES_H + + #include + #include + + #define U64_MAX UINT64_MAX + + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + + typedef int8_t s8; + typedef int16_t s16; + typedef int32_t s32; + typedef int64_t s64; + + typedef volatile u8 vu8; + typedef volatile u16 vu16; + typedef volatile u32 vu32; + typedef volatile u64 vu64; + + typedef volatile s8 vs8; + typedef volatile s16 vs16; + typedef volatile s32 vs32; + typedef volatile s64 vs64; + +#endif diff --git a/ios_fs/source/devices.h b/ios_fs/source/devices.h index 4c172ca..f3d2061 100644 --- a/ios_fs/source/devices.h +++ b/ios_fs/source/devices.h @@ -1,8 +1,6 @@ #ifndef DEVICES_H_ #define DEVICES_H_ -#define DEVICE_TYPE_SDCARD 0x06 - #define DEVICE_ID_SDCARD_REAL 0x43 #define DEVICE_ID_SDCARD_PATCHED 0xDA @@ -34,6 +32,60 @@ #define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2' #define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC ' +enum NodeTypes +{ + NODE_TYPE_DEV_DF = 0, + NODE_TYPE_DEV_ATFS = 1, + NODE_TYPE_DEV_ISFS = 2, + NODE_TYPE_DEV_WFS = 3, + NODE_TYPE_DEV_PCFS = 4, + NODE_TYPE_DEV_RBFS = 5, + NODE_TYPE_DEV_FAT = 6, + NODE_TYPE_DEV_FLA = 7, + NODE_TYPE_DEV_UMS = 8, + NODE_TYPE_DEV_AHCIMGR = 9, + NODE_TYPE_DEV_SHDD = 10, + NODE_TYPE_DEV_MD = 11, + NODE_TYPE_DEV_SCFM = 12, + NODE_TYPE_DEV_MMC = 13, + NODE_TYPE_DEV_TIMETRACE = 14, + NODE_TYPE_DEV_TCP_PCFS = 15 +}; + +enum DeviceTypes +{ + DEVICE_TYPE_SI = 0x01, + DEVICE_TYPE_ODD = 0x02, + DEVICE_TYPE_SLCCMPT = 0x03, + DEVICE_TYPE_SLC = 0x04, + DEVICE_TYPE_MLC = 0x05, + DEVICE_TYPE_SDCARD = 0x06, + DEVICE_TYPE_SD = 0x07, + DEVICE_TYPE_HFIO = 0x08, + DEVICE_TYPE_RAMDISK = 0x09, + DEVICE_TYPE_USB = 0x11, + DEVICE_TYPE_MLCORIG = 0x12 +}; + +enum FsTypes +{ + FS_TYPE_RAW = 0x8003, + FS_TYPE_FAT = 0x8004, + FS_TYPE_WFS = 0x8005, + FS_TYPE_ISFS = 0x8006, + FS_TYPE_ATFS = 0x8007 +}; + +typedef struct _fs_attach_info_t +{ + struct _fs_attach_info_t* next; + u16 fs_type; + u16 unkn_flags2; + u32 zeros[2]; + int (*fsAttach)(void *dev_struct, int unkn_one); + u8 allowed_devices[0x0C]; +} fs_attach_info_t; + typedef struct _stdio_nand_desc_t { u32 nand_type; // nand type diff --git a/ios_fs/source/dumper.c b/ios_fs/source/dumper.c index 65820ce..9174cbb 100644 --- a/ios_fs/source/dumper.c +++ b/ios_fs/source/dumper.c @@ -8,6 +8,7 @@ #include "text.h" #include "hardware_registers.h" #include "svc.h" +#include "../../common/kernel_commands.h" // the IO buffer is put behind everything else because there is no access to this region from IOS-FS it seems unsigned char io_buffer[0x40000] __attribute__((aligned(0x40))) __attribute__((section(".io_buffer"))); @@ -206,7 +207,7 @@ static void wait_format_confirmation(void) _printf(20, 30, "No NAND dump detected. SD Format and complete NAND dump required."); _printf(20, 40, "Press the POWER button to format SD card otherwise the console will reboot in %d seconds.", timeout/10); - if(svcRead32(LT_GPIO_IN) & GPIO_IN_POWER_BUTTON) + if(svcCustomKernelCommand(KERNEL_READ32, LT_GPIO_IN) & GPIO_IN_POWER_BUTTON) { break; } diff --git a/ios_fs/source/fsa.c b/ios_fs/source/fsa.c new file mode 100644 index 0000000..511e9ad --- /dev/null +++ b/ios_fs/source/fsa.c @@ -0,0 +1,222 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 +#include "types.h" +#include "devices.h" +#include "imports.h" +#include "fsa.h" + +//!------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! FSA redirection +//!------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +char* FSA_AttachVolume_FillDescription_hook(char *dst, const char *src, int size) +{ + char* ret = FS_STRNCPY(dst, src, size); + + u8 *volDescr = (u8 *)(dst - 0x1C); + + // copy in a fake volume name and enable flag that it is set + if( (FS_STRNCMP((char*)(volDescr + 0x1C), "usb", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) ) + { + FS_STRNCPY((char*)(volDescr + 0xAC), "usbfat1", 8); + *volDescr |= 0x40; + } + // let's do this for SD card to, for future SD card title loading maybe + /* + if( (FS_STRNCMP((char*)(volDescr + 0x1C), "sdcard", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) ) + { + FS_STRNCPY(volDescr + 0xAC, "sdfat", 7); + *volDescr |= 0x40; + } + */ + + + return ret; +} + +int FSA_AsyncCommandCallback_hook(int result, int reply) +{ + int (*FSA_ConvertErrorCode)(int result, int reply) = (void*)0x1071209C; + int res = FSA_ConvertErrorCode(result, reply); + + if(reply && (*(u32*)(reply + 0x42C) != 0)) + { + u32 devDescr = *(u32*)(reply + 0x42C); + int deviceType = *(u32*)(devDescr + 0x70); + + if(deviceType == DEVICE_TYPE_USB) // TODO: verify it is FAT USB and not WFS USB + { + u32 command = *(u32*)(reply + 0x1C); + + if(res < 0) + { + switch(command) + { + case 0x05: // FSMakeQuota -> 0x1D + case 0x1A: // FSFlushQuota -> 0x1E + case 0x1B: // FSRollbackQuota -> 0x1F + case 0x1C: // FSChangeOwner -> 0x70 + case 0x1D: // FSChangeMode -> 0x20 + case 0x1E: // FSRemoveQuota -> 0x72 // TODO: this actually removes the directory. we need to do something about it + case 0x20: // Unkn -> 0x74 + case 0x21: // FSMakeLinkAsync -> 0x75 // TODO: this is an issue on FAT. maybe create some file which has the name of the link in it? + case 0x16: // unkn but required on install + res = 0; + break; + case 0x04: + if(res == -196642) + { + // FS_SYSLOG_OUTPUT("FSA INVALID CHARACTERS IN CREATEDIR\n"); + res = 0; + } + break; + default: + break; + } + } + else + { + switch(command) + {/* + case 0x10: // FSGetStatFile + { + fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x2C)); + FS_SYSLOG_OUTPUT("FSGetStatFile: %08X %08X %08X %08X\n", fsStat->flag, fsStat->owner_id, fsStat->group_id, fsStat->size); + break; + }*/ + case 0x19: // FSGetInfo -> 0x18 + { + switch(*(u32*)(reply + 0x228)) + { + case 0x05: // FSGetStat + { + fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x22C)); + if((fsStat->flag & 0xF0000000) == 0x80000000) + { + // just make every directory a quota -> probably wrong :P + fsStat->flag |= 0xE0000000; + fsStat->quota_size = 0x4000000; // max quota size + } + break; + } + default: + break; + } + break; + } + default: + break; + } + } + } + } + + if(res < 0 && (*(u32*)(reply + 0x1C) != 0x19)) + FS_SYSLOG_OUTPUT("FSA TEST2: res %d %08X %08X %08X\n", res, result, reply, *(u32*)(reply + 0x1C)); + + + return res; +} + +int FSA_MakeQuota_hook(u32 * devDescr, u32 *commandStruct) +{ + int (*resolveNode)(u32 * devDescr) = (void*)0x1070EEDC; + int res = resolveNode(devDescr); + + if(devDescr[0x70/4] == DEVICE_TYPE_USB) + { + commandStruct[0x1C/4] = 4; + } + else + { + commandStruct[0x1C/4] = 5; + } + + return res; +} + +/* +int FSMakeQuota(int fsa, int client, const char *path, int mode, int unkn, unsigned int size) +{ + int (*callFunc)(int fsa, int client, const char *path, int mode, int unkn, unsigned int size) = (void*)0x1070BC9C; + + if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0) + { + mode = 0x666; + } + int res = callFunc(fsa, client, path, mode, unkn, size); + FS_SYSLOG_OUTPUT("FSMakeQuota: res %d %08X %08X %20s %08X %08X %08X\n", res, fsa, client, path, mode, unkn, size); + return res; +} + +int FSCreateDir(int fsa, int client, const char *path, int mode) +{ + int (*callFunc)(int fsa, int client, const char *path, int mode) = (void*)0x1070BEBC; + + if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0) + { + mode = 0x666; + } + int res = callFunc(fsa, client, path, mode); + FS_SYSLOG_OUTPUT("FSCreateDir: res %d %08X %08X %s %08X\n", res, fsa, client, path, mode); + return res; +} + +int FSChangeDir(int a1, char *dir) +{ + int (*callFunc)(int a1, char* a2) = (void*)0x1070EB7C; + int res = callFunc(a1, dir); + + FS_SYSLOG_OUTPUT("FSChangeDir: res %d %s\n", res, dir); + + return res; +} + +int FSOpenFile(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6) +{ + int (*callFunc)(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6) = (void*)0x1070AF08; + + if(FS_STRNCMP(dir, "/vol/mcp_devmgr", 15) == 0) + { + a4 = 0x666; + } + + int res = callFunc(a1, a2, dir, mode, a3, a4, a5, a6); + + FS_SYSLOG_OUTPUT("FSOpenFile: res %d %s %s %08X %08X %08X\n", res, dir, mode, a4, a5, a6); + + return res; +} + +int FSWriteFileIssueCommand(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8) +{ + int (*callFunc)(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8) = (void*)0x1070A7A4; + + int res = callFunc(a1, a2, a3, a4, a5, a6, a7, a8); + + FS_SYSLOG_OUTPUT("FSWriteFile: res %d %08X %08X %08X %08X %08X %08X\n", res, a3, a4, a5, a6, a7, a8); + + return res; +} +*/ diff --git a/ios_fs/source/fsa.h b/ios_fs/source/fsa.h new file mode 100644 index 0000000..7939857 --- /dev/null +++ b/ios_fs/source/fsa.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 _FSA_H_ +#define _FSA_H_ + +typedef struct +{ + u32 flag; + u32 permission; + u32 owner_id; + u32 group_id; + u32 size; // size in bytes + u32 physblock_size; // physical size on disk in bytes + u64 quota_size; + u32 id; + u32 ctime; + u32 mtime; + u32 unk2[0x0D]; +}fileStat_s; + +#endif diff --git a/ios_fs/source/function_hooks.s b/ios_fs/source/function_hooks.s index db64a94..6f99b21 100644 --- a/ios_fs/source/function_hooks.s +++ b/ios_fs/source/function_hooks.s @@ -5,10 +5,11 @@ .extern createDevThread_entry .globl createDevThread_hook createDevThread_hook: - push {r0,lr} + push {r0,r1,lr} ldr r0, [r4, #0x8] + mov r1, r7 bl createDevThread_entry - pop {r0,lr} + pop {r0,r1,lr} # restore original instruction pop {r4-r8,pc} @@ -56,6 +57,14 @@ sdcardRead_original: bx r4 .word 0x107BDDD4 +############################################################################################# +# FSA functions +############################################################################################# + .globl FSA_MakeQuota_asm_hook +FSA_MakeQuota_asm_hook: + mov r1, r5 + b FSA_MakeQuota_hook + ############################################################################################# # DEBUG STUFF ############################################################################################# diff --git a/ios_fs/source/imports.h b/ios_fs/source/imports.h index 03023a7..9532d33 100644 --- a/ios_fs/source/imports.h +++ b/ios_fs/source/imports.h @@ -11,9 +11,11 @@ #define FS_SLEEP ((void (*)(int))0x1071D668) #define FS_MEMCPY ((void* (*)(void*, const void*, u32))0x107F4F7C) #define FS_MEMSET ((void* (*)(void*, int, u32))0x107F5018) -#define FS_VSNPRINTF ((int (*)(char * s, size_t n, const char * format, va_list arg))0x107F5F68) -#define FS_SNPRINTF ((int (*)(char * s, size_t n, const char * format, ...))0x107F5FB4) - +#define FS_VSNPRINTF ((int (*)(char * s, u32 n, const char * format, va_list arg))0x107F5F68) +#define FS_SNPRINTF ((int (*)(char * s, u32 n, const char * format, ...))0x107F5FB4) +#define FS_STRNCMP ((int (*)(const char *s1, const char *s2, u32 size))0x107F6138) +#define FS_STRNCPY ((char* (*)(char *s1, const char *s2, u32 size))0x107F60DC) +#define FS_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0x107F0C84) #define FS_RAW_READ1 ((int (*)(int handle, u32 offset_high, u32 offset_low, u32 size, void* buf, void *callback, int callback_arg))0x10732BC0) #define FS_SDIO_DOREADWRITECOMMAND ((int (*)(int, void*, u32, void*, void*))0x10718A8C) diff --git a/ios_fs/source/main.c b/ios_fs/source/main.c index ef4a3d0..8a9106f 100644 --- a/ios_fs/source/main.c +++ b/ios_fs/source/main.c @@ -2,28 +2,56 @@ #include "sdio.h" #include "dumper.h" #include "imports.h" +#include "devices.h" +#include "svc.h" +#include "../../common/config_types.h" +#include "../../common/kernel_commands.h" -#define INITIALIZING_FLA 0x07 -#define INITIALIZING_MMC 0x0D - - -int getPhysicalDeviceHandle(u32 device); - -void createDevThread_entry(int initialization_type) +void createDevThread_entry(int node_type, u32 *dev_handles) { - if(initialization_type == INITIALIZING_MMC) + FS_SYSLOG_OUTPUT("FSA: %s thread created\n", (char*)dev_handles[0]); + + if(node_type == NODE_TYPE_DEV_MMC) { - sdcard_init(); + cfw_config_t cfw_config; + FS_MEMSET(&cfw_config, 0, sizeof(cfw_config)); + svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config); + + if(cfw_config.redNAND) + { + sdcard_init(); + } } - - //if(initialization_type == INITIALIZING_FLA) - //{ - //dump_nand_complete(); - //} - - if(initialization_type == 0x01) // unknown but after SLC init no read/write done at this point yet + else if(node_type == NODE_TYPE_DEV_UMS) { - if(check_nand_dump() == 0) + // instead of hooking into attach at 0x10732FBC...lets do this and let the system do the mount + fs_attach_info_t * info = (fs_attach_info_t *)(*(u32*)0x1091C2E4); + do + { + if(info->fs_type == FS_TYPE_FAT) + { + int i; + for(i = 0; i < sizeof(info->allowed_devices); i++) + { + if(info->allowed_devices[i] == 0) + { + info->allowed_devices[i] = DEVICE_TYPE_USB; + break; + } + } + break; + } + info = info->next; + } + while(info); + } + else if(node_type == NODE_TYPE_DEV_ATFS) // ATFS is started right before ISFS for slc/slccmpt + { + cfw_config_t cfw_config; + FS_MEMSET(&cfw_config, 0, sizeof(cfw_config)); + svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config); + + if(cfw_config.redNAND && (check_nand_dump() == 0)) { clearScreen(0x000000FF); _printf(20, 20, "welcome to redNAND!"); diff --git a/ios_fs/source/svc.h b/ios_fs/source/svc.h index ce959a0..97213e2 100644 --- a/ios_fs/source/svc.h +++ b/ios_fs/source/svc.h @@ -24,6 +24,6 @@ int svcInvalidateDCache(void* address, u32 size); int svcFlushDCache(void* address, u32 size); void svcShutdown(int shutdown_type); -u32 svcRead32(u32 addr); +int svcCustomKernelCommand(u32 command, ...); #endif diff --git a/ios_fs/source/svc.s b/ios_fs/source/svc.s index 638ff3c..aa07b1a 100644 --- a/ios_fs/source/svc.s +++ b/ios_fs/source/svc.s @@ -61,8 +61,8 @@ svcShutdown: .word 0xE7F072F0 bx lr -.global svcRead32 -.type svcRead32, %function -svcRead32: +.global svcCustomKernelCommand +.type svcCustomKernelCommand, %function +svcCustomKernelCommand: .word 0xE7F081F0 bx lr diff --git a/ios_kernel/source/config.h b/ios_kernel/source/config.h index 791a2b2..c515791 100644 --- a/ios_kernel/source/config.h +++ b/ios_kernel/source/config.h @@ -24,7 +24,7 @@ #ifndef __CONFIG_H_ #define __CONFIG_H_ -#include "../../src/cfw_config.h" +#include "../../common/config_types.h" extern cfw_config_t cfw_config; diff --git a/ios_kernel/source/elf_patcher.h b/ios_kernel/source/elf_patcher.h index 3033ea8..7f48afc 100644 --- a/ios_kernel/source/elf_patcher.h +++ b/ios_kernel/source/elf_patcher.h @@ -26,8 +26,10 @@ #include "types.h" -#define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) -#define ARM_BL(addr, func) (0xEB000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) +#define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB +#define ARM_BL(addr, func) (0xEB000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB +#define THUMB_B(addr, func) ((0xE000 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x7FF))) // +-2KB +#define THUMB_BL(addr, func) ((0xF000F800 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x0FFF)) | ((((u32)(func) - (u32)(addr) - 4) << 4) & 0x7FFF000)) // +-4MB typedef struct { diff --git a/ios_kernel/source/ios_acp_patches.c b/ios_kernel/source/ios_acp_patches.c new file mode 100644 index 0000000..4272b69 --- /dev/null +++ b/ios_kernel/source/ios_acp_patches.c @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 "types.h" +#include "elf_patcher.h" +#include "config.h" +#include "ios_acp_patches.h" +#include "../../ios_acp/ios_acp.bin.h" +#include "../../ios_acp/ios_acp_syms.h" + +#define ACP_CODE_BASE_PHYS_ADDR (-0xE0000000 + 0x12900000) + +extern const patch_table_t acp_patches_table[]; +extern const patch_table_t acp_patches_table_end[]; + +u32 acp_get_phys_code_base(void) +{ + return _text_start + ACP_CODE_BASE_PHYS_ADDR; +} + +void acp_run_patches(u32 ios_elf_start) +{ + section_write(ios_elf_start, _text_start, (void*)acp_get_phys_code_base(), _text_end - _text_start); + + // hook acp fsa raw read function + section_write_word(ios_elf_start, 0xE00601F0, ARM_BL(0xE00601F0, ACP_FSARawRead_hook)); + + // patch logs to output more info + section_write_word(ios_elf_start, 0xE009801C, ARM_B(0xE009801C, 0xE00C4D54)); + section_write_word(ios_elf_start, 0xE00D87B0, ARM_B(0xE00D87B0, 0xE00C4D54)); + section_write_word(ios_elf_start, 0xE00D6DE8, ARM_B(0xE00D6DE8, 0xE00C4D54)); + section_write_word(ios_elf_start, 0xE009A0C4, 0xE3A00000); + + // patch acp remove quota to always try recursive directory remove after remove quota + section_write_word(ios_elf_start, 0xE002E170, 0xEA000021); + + u32 patch_count = (u32)(((u8*)acp_patches_table_end) - ((u8*)acp_patches_table)) / sizeof(patch_table_t); + patch_table_entries(ios_elf_start, acp_patches_table, patch_count); +} diff --git a/ios_kernel/source/ios_acp_patches.h b/ios_kernel/source/ios_acp_patches.h new file mode 100644 index 0000000..a28d329 --- /dev/null +++ b/ios_kernel/source/ios_acp_patches.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2016 + * 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 _ACP_PATCHES_H_ +#define _ACP_PATCHES_H_ + +u32 acp_get_phys_code_base(void); +void acp_run_patches(u32 ios_elf_start); + +#endif diff --git a/ios_kernel/source/ios_acp_patches_asm.s b/ios_kernel/source/ios_acp_patches_asm.s new file mode 100644 index 0000000..ab4d38b --- /dev/null +++ b/ios_kernel/source/ios_acp_patches_asm.s @@ -0,0 +1,11 @@ +.arm + +patch_wfs_partition_check: + mov r0, #0 + +.globl acp_patches_table, acp_patches_table_end +acp_patches_table: +# origin data size + .word 0xE00605D0, patch_wfs_partition_check, 4 +acp_patches_table_end: + diff --git a/ios_kernel/source/ios_fs_patches.c b/ios_kernel/source/ios_fs_patches.c index 5576c65..6c4e8ee 100644 --- a/ios_kernel/source/ios_fs_patches.c +++ b/ios_kernel/source/ios_fs_patches.c @@ -24,6 +24,7 @@ #include "types.h" #include "elf_patcher.h" #include "ios_fs_patches.h" +#include "config.h" #include "../../ios_fs/ios_fs_syms.h" #define FS_PHYS_DIFF 0 @@ -63,22 +64,39 @@ void fs_run_patches(u32 ios_elf_start) // patch FS logging section_write_word(ios_elf_start, FS_PRINTF_SYSLOG, ARM_B(FS_PRINTF_SYSLOG, FS_SYSLOG_OUTPUT)); - section_write_word(ios_elf_start, CALL_FS_REGISTERMDPHYSICALDEVICE, ARM_BL(CALL_FS_REGISTERMDPHYSICALDEVICE, registerMdDevice_hook)); - section_write_word(ios_elf_start, FS_GETMDDEVICEBYID + 8, ARM_BL((FS_GETMDDEVICEBYID + 8), getMdDeviceById_hook)); + if(cfw_config.redNAND) + { + section_write_word(ios_elf_start, CALL_FS_REGISTERMDPHYSICALDEVICE, ARM_BL(CALL_FS_REGISTERMDPHYSICALDEVICE, registerMdDevice_hook)); + section_write_word(ios_elf_start, FS_GETMDDEVICEBYID + 8, ARM_BL((FS_GETMDDEVICEBYID + 8), getMdDeviceById_hook)); - section_write_word(ios_elf_start, FS_SDCARD_READ1, ARM_B(FS_SDCARD_READ1, sdcardRead_patch)); - section_write_word(ios_elf_start, FS_SDCARD_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_patch)); + section_write_word(ios_elf_start, FS_SDCARD_READ1, ARM_B(FS_SDCARD_READ1, sdcardRead_patch)); + section_write_word(ios_elf_start, FS_SDCARD_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_patch)); - section_write_word(ios_elf_start, FS_SLC_READ1, ARM_B(FS_SLC_READ1, slcRead1_patch)); - section_write_word(ios_elf_start, FS_SLC_READ2, ARM_B(FS_SLC_READ2, slcRead2_patch)); - section_write_word(ios_elf_start, FS_SLC_WRITE1, ARM_B(FS_SLC_WRITE1, slcWrite1_patch)); - section_write_word(ios_elf_start, FS_SLC_WRITE2, ARM_B(FS_SLC_WRITE2, slcWrite2_patch)); + section_write_word(ios_elf_start, FS_SLC_READ1, ARM_B(FS_SLC_READ1, slcRead1_patch)); + section_write_word(ios_elf_start, FS_SLC_READ2, ARM_B(FS_SLC_READ2, slcRead2_patch)); + section_write_word(ios_elf_start, FS_SLC_WRITE1, ARM_B(FS_SLC_WRITE1, slcWrite1_patch)); + section_write_word(ios_elf_start, FS_SLC_WRITE2, ARM_B(FS_SLC_WRITE2, slcWrite2_patch)); - //section_write_word(ios_elf_start, FS_USB_READ, ARM_B(FS_USB_READ, usbRead_patch)); - //section_write_word(ios_elf_start, FS_USB_WRITE, ARM_B(FS_USB_WRITE, usbWrite_patch)); + //section_write_word(ios_elf_start, FS_USB_READ, ARM_B(FS_USB_READ, usbRead_patch)); + //section_write_word(ios_elf_start, FS_USB_WRITE, ARM_B(FS_USB_WRITE, usbWrite_patch)); + } + + section_write_word(ios_elf_start, 0x1070F87C, ARM_BL(0x1070F87C, FSA_AttachVolume_FillDescription_hook)); + section_write_word(ios_elf_start, 0x10700EFC, ARM_BL(0x10700EFC, FSA_AsyncCommandCallback_hook)); + // patch mounting FAT and allow all devices instead of only SD card + section_write_word(ios_elf_start, 0x1078E074, 0xEA000002); + // patch FSA_MakeQuota to not store command -> command is modified depending on wether it is USB FAT or not + section_write_word(ios_elf_start, 0x1070BE0C, 0xE1A00000); + section_write_word(ios_elf_start, 0x1070BE00, ARM_BL(0x1070BE00, FSA_MakeQuota_asm_hook)); section_write_word(ios_elf_start, FS_CREATEDEVTHREAD_HOOK, ARM_B(FS_CREATEDEVTHREAD_HOOK, createDevThread_hook)); u32 patch_count = (u32)(((u8*)fs_patches_table_end) - ((u8*)fs_patches_table)) / sizeof(patch_table_t); patch_table_entries(ios_elf_start, fs_patches_table, patch_count); + + //section_write_word(ios_elf_start, 0x10701F6C, ARM_BL(0x10701F6C, FSMakeQuota)); + //section_write_word(ios_elf_start, 0x10702764, ARM_BL(0x10702764, FSCreateDir)); + //section_write_word(ios_elf_start, 0x1070278C, ARM_BL(0x1070278C, FSChangeDir)); + //section_write_word(ios_elf_start, 0x107024B4, ARM_BL(0x107024B4, FSOpenFile)); + //section_write_word(ios_elf_start, 0x10703F4C, ARM_BL(0x10703F4C, FSWriteFileIssueCommand)); } diff --git a/ios_kernel/source/ios_mcp_patches.c b/ios_kernel/source/ios_mcp_patches.c index ed02693..d5e78ba 100644 --- a/ios_kernel/source/ios_mcp_patches.c +++ b/ios_kernel/source/ios_mcp_patches.c @@ -52,8 +52,11 @@ void mcp_run_patches(u32 ios_elf_start) section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24); } - section_write_word(ios_elf_start, (_text_start - 4), cfw_config.launchImage); - u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t); patch_table_entries(ios_elf_start, mcp_patches_table, patch_count); + + // patch MCP syslogs + //section_write_word(ios_elf_start, 0x05055438, ARM_B(0x05055438, 0x0503DCF8)); + //section_write_word(ios_elf_start, 0x05056C2C, ARM_B(0x05056C2C, 0x0503DCF8)); + //section_write_word(ios_elf_start, 0x0500A4D2, THUMB_BL(0x0500A4D2, mcpThumb2ArmLog)); } diff --git a/ios_kernel/source/ios_mcp_patches_asm.s b/ios_kernel/source/ios_mcp_patches_asm.s index 2b42c08..dc4e2a9 100644 --- a/ios_kernel/source/ios_mcp_patches_asm.s +++ b/ios_kernel/source/ios_mcp_patches_asm.s @@ -5,6 +5,11 @@ # mov r0, #0 # mov r0, #0 +patch_wfs_partition_check: + .thumb + mov r0, #0 + mov r0, #0 + patch_MCP_authentication_check: .thumb mov r0, #0 @@ -29,6 +34,8 @@ mcp_patches_table: .word 0x05052C44, patch_IOSC_VerifyPubkeySign, 8 .word 0x05052A90, patch_cert_verification, 8 .word 0x05054D6C, patch_cached_cert_check, 8 + .word 0x0502ADF6, patch_wfs_partition_check, 4 +# .word 0x05014AD8, patch_wfs_partition_check, 4 # over an hour, MCP crash prevention .word 0x05022474, 0xFFFFFFFF, 4 # MCP patches end here actually but lets tread the ACP patches as MCP as there are only patches diff --git a/ios_kernel/source/kernel_patches.c b/ios_kernel/source/kernel_patches.c index 3aafa73..b8580a1 100644 --- a/ios_kernel/source/kernel_patches.c +++ b/ios_kernel/source/kernel_patches.c @@ -22,8 +22,10 @@ * distribution. ***************************************************************************/ #include "types.h" +#include "../../common/kernel_commands.h" #include "elf_patcher.h" #include "ios_mcp_patches.h" +#include "ios_acp_patches.h" #include "ios_fs_patches.h" #include "ios_bsp_patches.h" #include "kernel_patches.h" @@ -55,9 +57,35 @@ static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] = 0x00000001 // pid (MCP) }; -static u32 kernel_syscall_0x81(u32 address) +static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3) { - return *(volatile u32*)address; + switch(command) + { + case KERNEL_READ32: + { + return *(volatile u32*)arg1; + } + case KERNEL_WRITE32: + { + *(volatile u32*)arg1 = arg2; + break; + } + case KERNEL_MEMCPY: + { + //set_domain_register(0xFFFFFFFF); + kernel_memcpy((void*)arg1, (void*) arg2, arg3); + break; + } + case KERNEL_GET_CFW_CONFIG: + { + //set_domain_register(0xFFFFFFFF); + kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config)); + break; + } + default: + return -1; + } + return 0; } static int kernel_read_otp_internal(int index, void* out_buf, u32 size) @@ -101,14 +129,11 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H) //! try to keep the order of virt. addresses to reduce the memmove amount mcp_run_patches(ios_elf_start); kernel_run_patches(ios_elf_start); + fs_run_patches(ios_elf_start); + acp_run_patches(ios_elf_start); - if(cfw_config.redNAND) - { - fs_run_patches(ios_elf_start); - - if(cfw_config.seeprom_red) - bsp_run_patches(ios_elf_start); - } + if(cfw_config.redNAND && cfw_config.seeprom_red) + bsp_run_patches(ios_elf_start); restore_mmu(control_register); enable_interrupts(level); @@ -120,7 +145,7 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H) void kernel_run_patches(u32 ios_elf_start) { section_write(ios_elf_start, (u32)__KERNEL_CODE_START, __KERNEL_CODE_START, __KERNEL_CODE_END - __KERNEL_CODE_START); - section_write_word(ios_elf_start, 0x0812A120, ARM_BL(0x0812A120, kernel_launch_ios)); + //section_write_word(ios_elf_start, 0x0812A120, ARM_BL(0x0812A120, kernel_launch_ios)); section_write(ios_elf_start, 0x08140DE0, KERNEL_MCP_IOMAPPINGS_STRUCT, sizeof(KERNEL_MCP_IOMAPPINGS_STRUCT)); diff --git a/ios_kernel/source/main.c b/ios_kernel/source/main.c index 2f8c9d6..b08a605 100644 --- a/ios_kernel/source/main.c +++ b/ios_kernel/source/main.c @@ -26,6 +26,7 @@ #include "utils.h" #include "redirection_setup.h" #include "ios_mcp_patches.h" +#include "ios_acp_patches.h" #include "ios_fs_patches.h" #include "ios_bsp_patches.h" #include "instant_patches.h" @@ -99,17 +100,15 @@ int _main() kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - if(cfw_config.redNAND) - { - kernel_memcpy((void*)fs_get_phys_code_base(), payloads->data, payloads->size); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + kernel_memcpy((void*)fs_get_phys_code_base(), payloads->data, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - if(cfw_config.seeprom_red) - { - kernel_memcpy((void*)bsp_get_phys_code_base(), payloads->data, payloads->size); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - } - } + if(cfw_config.redNAND && cfw_config.seeprom_red) + kernel_memcpy((void*)bsp_get_phys_code_base(), payloads->data, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + kernel_memcpy((void*)acp_get_phys_code_base(), payloads->data, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); diff --git a/ios_kernel/source/utils.h b/ios_kernel/source/utils.h index b9a2a8a..24dfaf9 100644 --- a/ios_kernel/source/utils.h +++ b/ios_kernel/source/utils.h @@ -48,4 +48,9 @@ static inline void restore_mmu(unsigned int control_register) asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register)); } +static inline void set_domain_register(unsigned int domain_register) +{ + asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register)); +} + #endif diff --git a/ios_mcp/link.ld b/ios_mcp/link.ld index 89a76a1..a5ddeac 100644 --- a/ios_mcp/link.ld +++ b/ios_mcp/link.ld @@ -10,7 +10,7 @@ SECTIONS } _text_end = .; - .bss 0x050BE000 : { + .bss 0x050BD000 : { _bss_start = .; *(.bss*); } diff --git a/ios_mcp/source/ipc.c b/ios_mcp/source/ipc.c index 53b83dd..537af36 100644 --- a/ios_mcp/source/ipc.c +++ b/ios_mcp/source/ipc.c @@ -30,6 +30,8 @@ #include "text.h" #include "logger.h" #include "fsa.h" +#include "wupserver.h" +#include "../../common/kernel_commands.h" #define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 #define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 @@ -40,6 +42,7 @@ #define IOCTL_MEM_WRITE 0x00 #define IOCTL_MEM_READ 0x01 #define IOCTL_SVC 0x02 +#define IOCTL_KILL_SERVER 0x03 #define IOCTL_MEMCPY 0x04 #define IOCTL_REPEATED_WRITE 0x05 #define IOCTL_KERN_READ32 0x06 @@ -71,6 +74,7 @@ #define IOCTL_FSA_RAW_CLOSE 0x57 #define IOCTL_FSA_CHANGEMODE 0x58 +static int ipcNodeKilled; static u8 threadStack[0x1000] __attribute__((aligned(0x20))); static int ipc_ioctl(ipcmessage *message) @@ -123,6 +127,12 @@ static int ipc_ioctl(ipcmessage *message) } break; } + case IOCTL_KILL_SERVER: + { + ipcNodeKilled = 1; + wupserver_deinit(); + break; + } case IOCTL_MEMCPY: { if(message->ioctl.length_in < 12) @@ -180,7 +190,7 @@ static int ipc_ioctl(ipcmessage *message) { for(u32 i = 0; i < (message->ioctl.length_io/4); i++) { - message->ioctl.buffer_io[i] = svcRead32(message->ioctl.buffer_in[0] + i * 4); + message->ioctl.buffer_io[i] = svcCustomKernelCommand(KERNEL_READ32, message->ioctl.buffer_in[0] + i * 4); } } break; @@ -420,61 +430,76 @@ static int ipc_thread(void *arg) int queueId = svcCreateMessageQueue(messageQueue, sizeof(messageQueue) / 4); - if(svcRegisterResourceManager("/dev/iosuhax", queueId) != 0) + if(svcRegisterResourceManager("/dev/iosuhax", queueId) == 0) { - return 0; + while(!ipcNodeKilled) + { + res = svcReceiveMessage(queueId, &message, 0); + if(res < 0) + { + usleep(10000); + continue; + } + + switch(message->command) + { + case IOS_OPEN: + { + log_printf("IOS_OPEN\n"); + res = 0; + break; + } + case IOS_CLOSE: + { + log_printf("IOS_CLOSE\n"); + res = 0; + break; + } + case IOS_IOCTL: + { + log_printf("IOS_IOCTL\n"); + res = ipc_ioctl(message); + break; + } + case IOS_IOCTLV: + { + log_printf("IOS_IOCTLV\n"); + res = 0; + break; + } + default: + { + log_printf("unexpected command 0x%X\n", message->command); + res = IOS_ERROR_UNKNOWN_VALUE; + break; + } + } + + svcResourceReply(message, res); + } } - while(1) - { - res = svcReceiveMessage(queueId, &message, 0); - if(res < 0) - { - usleep(10000); - continue; - } - - switch(message->command) - { - case IOS_OPEN: - { - log_printf("IOS_OPEN\n"); - res = 0; - break; - } - case IOS_CLOSE: - { - log_printf("IOS_CLOSE\n"); - res = 0; - break; - } - case IOS_IOCTL: - { - log_printf("IOS_IOCTL\n"); - res = ipc_ioctl(message); - break; - } - case IOS_IOCTLV: - { - log_printf("IOS_IOCTLV\n"); - res = 0; - break; - } - default: - { - log_printf("unexpected command 0x%X\n", message->command); - res = IOS_ERROR_UNKNOWN_VALUE; - break; - } - } - - svcResourceReply(message, res); - } + svcDestroyMessageQueue(queueId); + return 0; } void ipc_init(void) { + ipcNodeKilled = 0; + int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1); if(threadId >= 0) svcStartThread(threadId); } + +void ipc_deinit(void) +{ + int fd = svcOpen("/dev/iosuhax", 0); + if(fd >= 0) + { + int dummy = 0; + svcIoctl(fd, IOCTL_KILL_SERVER, &dummy, sizeof(dummy), &dummy, sizeof(dummy)); + svcClose(fd); + } + +} diff --git a/ios_mcp/source/ipc.h b/ios_mcp/source/ipc.h index 72aac08..72cf8be 100644 --- a/ios_mcp/source/ipc.h +++ b/ios_mcp/source/ipc.h @@ -2,5 +2,6 @@ #define _IPC_H_ void ipc_init(); +void ipc_deinit(); #endif diff --git a/ios_mcp/source/main.c b/ios_mcp/source/main.c index 6468783..60d6f36 100644 --- a/ios_mcp/source/main.c +++ b/ios_mcp/source/main.c @@ -1,247 +1,30 @@ #include #include #include -#include "imports.h" -#include "net_ifmgr_ncl.h" -#include "socket.h" -#include "fsa.h" +#include "wupserver.h" +#include "ipc.h" #include "svc.h" #include "text.h" -#include "logger.h" -#include "ipc.h" +#include "../../common/config_types.h" +#include "../../common/kernel_commands.h" -static bool serverKilled; static int threadsStarted = 0; -// overwrites command_buffer with response -// returns length of response (or 0 for no response, negative for error) -int serverCommandHandler(u32* command_buffer, u32 length) -{ - if(!command_buffer || !length) return -1; - - int out_length = 4; - - switch(command_buffer[0]) - { - case 0: - // write - // [cmd_id][addr] - { - void* dst = (void*)command_buffer[1]; - - memcpy(dst, &command_buffer[2], length - 8); - } - break; - case 1: - // read - // [cmd_id][addr][length] - { - void* src = (void*)command_buffer[1]; - length = command_buffer[2]; - - memcpy(&command_buffer[1], src, length); - out_length = length + 4; - } - break; - case 2: - // svc - // [cmd_id][svc_id] - { - int svc_id = command_buffer[1]; - int size_arguments = length - 8; - - u32 arguments[8]; - memset(arguments, 0x00, sizeof(arguments)); - memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4)); - - // return error code as data - out_length = 8; - command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); - } - break; - case 3: - // kill - // [cmd_id] - { - serverKilled = true; - } - break; - case 4: - // memcpy - // [dst][src][size] - { - void* dst = (void*)command_buffer[1]; - void* src = (void*)command_buffer[2]; - int size = command_buffer[3]; - - memcpy(dst, src, size); - } - break; - case 5: - // repeated-write - // [address][value][n] - { - u32* dst = (u32*)command_buffer[1]; - u32* cache_range = (u32*)(command_buffer[1] & ~0xFF); - u32 value = command_buffer[2]; - u32 n = command_buffer[3]; - - u32 old = *dst; - int i; - for(i = 0; i < n; i++) - { - if(*dst != old) - { - if(*dst == 0x0) old = *dst; - else - { - *dst = value; - svcFlushDCache(cache_range, 0x100); - break; - } - }else - { - svcInvalidateDCache(cache_range, 0x100); - usleep(50); - } - } - } - break; - default: - // unknown command - return -2; - break; - } - - // no error ! - command_buffer[0] = 0x00000000; - return out_length; -} - -void serverClientHandler(int sock) -{ - u32 command_buffer[0x180]; - - while(!serverKilled) - { - int ret = recv(sock, command_buffer, sizeof(command_buffer), 0); - - if(ret <= 0) break; - - ret = serverCommandHandler(command_buffer, ret); - - if(ret > 0) - { - send(sock, command_buffer, ret, 0); - }else if(ret < 0) - { - send(sock, &ret, sizeof(int), 0); - } - } - - closesocket(sock); -} - -void serverListenClients() -{ - int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - struct sockaddr_in server; - - memset(&server, 0x00, sizeof(server)); - - server.sin_family = AF_INET; - server.sin_port = 1337; - server.sin_addr.s_addr = 0; - - if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0) - { - closesocket(sock); - return; - } - - if(listen(sock, 1) < 0) - { - closesocket(sock); - return; - } - - while(!serverKilled) - { - int csock = accept(sock, NULL, NULL); - if(csock < 0) - break; - - serverClientHandler(csock); - } - - closesocket(sock); -} - -int _main(void *arg) -{ - while(ifmgrnclInit() <= 0) - { - //print(0, 0, "opening /dev/net/ifmgr/ncl..."); - usleep(1000); - } - - while(true) - { - u16 out0, out1; - - int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0); - if(!ret0 && out0 == 1) break; - - int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1); - if(!ret1 && out1 == 1) break; - - //print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1); - - usleep(1000); - } - - while(socketInit() <= 0) - { - //print(0, 0, "opening /dev/socket..."); - usleep(1000); - } - - log_init(0xC0A8B203); - - //print(0, 0, "opened /dev/socket !"); - usleep(5*1000*1000); - //print(0, 10, "attempting sockets !"); - - serverKilled = false; - - while(1) - { - if(!serverKilled) - { - serverListenClients(); - } - usleep(1000*1000); - } - return 0; -} - int _startMainThread(void) { if(threadsStarted == 0) { threadsStarted = 1; + cfw_config_t cfw_config; + memset(&cfw_config, 0, sizeof(cfw_config)); + svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config); - int * launchImageConfigured = (int *)(0x05116000 - 4); - if(*launchImageConfigured != 0) + if(cfw_config.launchImage) { drawSplashScreen(); } - int threadId = svcCreateThread(_main, 0, (u32*)(0x050BD000 + 0x1000), 0x1000, 0x78, 1); - if(threadId >= 0) - svcStartThread(threadId); - + wupserver_init(); ipc_init(); } return 0; diff --git a/ios_mcp/source/socket.c b/ios_mcp/source/socket.c index ca12f99..13b2c78 100644 --- a/ios_mcp/source/socket.c +++ b/ios_mcp/source/socket.c @@ -153,6 +153,20 @@ int listen(int sockfd, int backlog) return ret; } +int shutdown(int sockfd, int how) +{ + u8* iobuf = allocIobuf(0x8); + u32* inbuf = (u32*)iobuf; + + inbuf[0] = sockfd; + inbuf[1] = how; + + int ret = svcIoctl(socket_handle, 0x10, inbuf, 0x8, NULL, 0); + + freeIobuf(iobuf); + return ret; +} + int recv(int sockfd, void *buf, size_t len, int flags) { if(!len) return -101; diff --git a/ios_mcp/source/svc.h b/ios_mcp/source/svc.h index 8aa8aad..0ef8c6d 100644 --- a/ios_mcp/source/svc.h +++ b/ios_mcp/source/svc.h @@ -23,9 +23,10 @@ int svcFlushDCache(void* address, u32 size); int svcCreateThread(int (*callback)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, int detached); int svcStartThread(int threadId); int svcCreateMessageQueue(u32 *ptr, u32 n_msgs); +int svcDestroyMessageQueue(int queueid); int svcRegisterResourceManager(const char* device, int queueid); int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags); int svcResourceReply(ipcmessage * ipc_message, u32 result); -u32 svcRead32(u32 addr); +int svcCustomKernelCommand(u32 command, ...); #endif diff --git a/ios_mcp/source/svc.s b/ios_mcp/source/svc.s index 1abd79a..87518ee 100644 --- a/ios_mcp/source/svc.s +++ b/ios_mcp/source/svc.s @@ -20,6 +20,12 @@ svcCreateMessageQueue: .word 0xE7F00CF0 bx lr +.global svcDestroyMessageQueue +.type svcDestroyMessageQueue, %function +svcDestroyMessageQueue: + .word 0xE7F00DF0 + bx lr + .global svcReceiveMessage .type svcReceiveMessage, %function svcReceiveMessage: @@ -92,8 +98,8 @@ svcFlushDCache: .word 0xE7F052F0 bx lr -.global svcRead32 -.type svcRead32, %function -svcRead32: +.global svcCustomKernelCommand +.type svcCustomKernelCommand, %function +svcCustomKernelCommand: .word 0xE7F081F0 bx lr diff --git a/ios_mcp/source/wupserver.c b/ios_mcp/source/wupserver.c new file mode 100644 index 0000000..b60c2d4 --- /dev/null +++ b/ios_mcp/source/wupserver.c @@ -0,0 +1,250 @@ +#include +#include +#include +#include "imports.h" +#include "net_ifmgr_ncl.h" +#include "socket.h" +#include "fsa.h" +#include "svc.h" +#include "text.h" +#include "logger.h" +#include "ipc.h" + +static int serverKilled; +static int serverSocket; +static u8 threadStack[0x1000] __attribute__((aligned(0x20))); + +// overwrites command_buffer with response +// returns length of response (or 0 for no response, negative for error) +static int serverCommandHandler(u32* command_buffer, u32 length) +{ + if(!command_buffer || !length) return -1; + + int out_length = 4; + + switch(command_buffer[0]) + { + case 0: + // write + // [cmd_id][addr] + { + void* dst = (void*)command_buffer[1]; + + memcpy(dst, &command_buffer[2], length - 8); + } + break; + case 1: + // read + // [cmd_id][addr][length] + { + void* src = (void*)command_buffer[1]; + length = command_buffer[2]; + + memcpy(&command_buffer[1], src, length); + out_length = length + 4; + } + break; + case 2: + // svc + // [cmd_id][svc_id] + { + int svc_id = command_buffer[1]; + int size_arguments = length - 8; + + u32 arguments[8]; + memset(arguments, 0x00, sizeof(arguments)); + memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4)); + + // return error code as data + out_length = 8; + command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); + } + break; + case 3: + // kill + // [cmd_id] + { + serverKilled = 1; + ipc_deinit(); + } + break; + case 4: + // memcpy + // [dst][src][size] + { + void* dst = (void*)command_buffer[1]; + void* src = (void*)command_buffer[2]; + int size = command_buffer[3]; + + memcpy(dst, src, size); + } + break; + case 5: + // repeated-write + // [address][value][n] + { + u32* dst = (u32*)command_buffer[1]; + u32* cache_range = (u32*)(command_buffer[1] & ~0xFF); + u32 value = command_buffer[2]; + u32 n = command_buffer[3]; + + u32 old = *dst; + int i; + for(i = 0; i < n; i++) + { + if(*dst != old) + { + if(*dst == 0x0) old = *dst; + else + { + *dst = value; + svcFlushDCache(cache_range, 0x100); + break; + } + }else + { + svcInvalidateDCache(cache_range, 0x100); + usleep(50); + } + } + } + break; + default: + // unknown command + return -2; + break; + } + + // no error ! + command_buffer[0] = 0x00000000; + return out_length; +} + +static void serverClientHandler(int sock) +{ + u32 command_buffer[0x180]; + + while(!serverKilled) + { + int ret = recv(sock, command_buffer, sizeof(command_buffer), 0); + + if(ret <= 0) break; + + ret = serverCommandHandler(command_buffer, ret); + + if(ret > 0) + { + send(sock, command_buffer, ret, 0); + }else if(ret < 0) + { + send(sock, &ret, sizeof(int), 0); + } + } + + closesocket(sock); +} + +static void serverListenClients() +{ + serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + struct sockaddr_in server; + + memset(&server, 0x00, sizeof(server)); + + server.sin_family = AF_INET; + server.sin_port = 1337; + server.sin_addr.s_addr = 0; + + if(bind(serverSocket, (struct sockaddr *)&server, sizeof(server)) < 0) + { + closesocket(serverSocket); + return; + } + + if(listen(serverSocket, 1) < 0) + { + closesocket(serverSocket); + return; + } + + while(!serverKilled) + { + int csock = accept(serverSocket, NULL, NULL); + if(csock < 0) + break; + + serverClientHandler(csock); + } + + closesocket(serverSocket); + serverSocket = -1; +} + +static int wupserver_thread(void *arg) +{ + while(ifmgrnclInit() <= 0) + { + //print(0, 0, "opening /dev/net/ifmgr/ncl..."); + usleep(1000); + } + + while(true) + { + u16 out0, out1; + + int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0); + if(!ret0 && out0 == 1) break; + + int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1); + if(!ret1 && out1 == 1) break; + + //print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1); + + usleep(1000); + } + + while(socketInit() <= 0) + { + //print(0, 0, "opening /dev/socket..."); + usleep(1000); + } + + log_init(0xC0A8B203); + + //print(0, 0, "opened /dev/socket !"); + usleep(5*1000*1000); + //print(0, 10, "attempting sockets !"); + + while(1) + { + if(!serverKilled) + { + serverListenClients(); + } + else + { + break; + } + usleep(1000*1000); + } + + log_deinit(); + return 0; +} + +void wupserver_init(void) +{ + serverSocket = -1; + serverKilled = 0; + + int threadId = svcCreateThread(wupserver_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1); + if(threadId >= 0) + svcStartThread(threadId); +} + +void wupserver_deinit(void) +{ + serverKilled = 1; + shutdown(serverSocket, SHUT_RDWR); +} diff --git a/ios_mcp/source/wupserver.h b/ios_mcp/source/wupserver.h new file mode 100644 index 0000000..506349a --- /dev/null +++ b/ios_mcp/source/wupserver.h @@ -0,0 +1,7 @@ +#ifndef WUPSERVER_H +#define WUPSERVER_H + +void wupserver_init(void); +void wupserver_deinit(void); + +#endif diff --git a/ios_mcp/wupclient.py b/ios_mcp/wupclient.py index 9f5c094..41ba104 100644 --- a/ios_mcp/wupclient.py +++ b/ios_mcp/wupclient.py @@ -325,7 +325,7 @@ class wupclient: # print(data[:data.index(0)].decode("ascii")) # break # else: - print(data.decode("ascii")) + print(data) # file management def get_fsa_handle(self): diff --git a/src/cfw_config.h b/src/cfw_config.h index 92a8c17..cbae12e 100644 --- a/src/cfw_config.h +++ b/src/cfw_config.h @@ -28,18 +28,7 @@ #define APP_PATH "sd:/wiiu/apps/mocha" #define CONFIG_PATH (APP_PATH "/config.ini") -typedef struct -{ - int viewMode; - int directLaunch; - int launchImage; - int noIosReload; - int launchSysMenu; - int redNAND; - int seeprom_red; - int otp_red; - int syshaxXml; -} cfw_config_t; +#include "../common/config_types.h" void default_config(cfw_config_t * config); int read_config(cfw_config_t * config); diff --git a/src/fs/fs_utils.c b/src/fs/fs_utils.c index efa2e55..d990df3 100644 --- a/src/fs/fs_utils.c +++ b/src/fs/fs_utils.c @@ -96,7 +96,9 @@ int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size) //! sign is optional input if(size) + { *size = filesize; + } return filesize; } diff --git a/src/ios_exploit.c b/src/ios_exploit.c index d9785b3..d2b7b18 100644 --- a/src/ios_exploit.c +++ b/src/ios_exploit.c @@ -1,7 +1,7 @@ #include #include #include "dynamic_libs/os_functions.h" -#include "cfw_config.h" +#include "ios_exploit.h" #define ALIGN4(x) (((x) + 3) & ~3) @@ -36,6 +36,7 @@ typedef struct #include "../ios_fs/ios_fs.bin.h" #include "../ios_bsp/ios_bsp.bin.h" #include "../ios_mcp/ios_mcp.bin.h" +#include "../ios_acp/ios_acp.bin.h" /* ROP CHAIN STARTS HERE (0x1015BD78) */ @@ -324,19 +325,17 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) memcpy(payloads->data, ios_usb_bin, payloads->size); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - if(config->redNAND) - { - 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_fs_bin); + memcpy(payloads->data, ios_fs_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - if(config->seeprom_red) - { - 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_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); @@ -361,7 +360,6 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); } } - pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; @@ -385,28 +383,30 @@ static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) int ExecuteIOSExploit(cfw_config_t * config) { int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); - if(iosuhaxFd < 0) + if(iosuhaxFd >= 0) { - //! execute exploit - int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); - if(dev_uhs_0_handle < 0) - return dev_uhs_0_handle; + int dummy = 0; - 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); + IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy)); - uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} - - IOS_Close(dev_uhs_0_handle); - } - else - { //! 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) + 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); return 0; } diff --git a/src/menu.c b/src/menu.c index 50bb5e3..71b7dc9 100644 --- a/src/menu.c +++ b/src/menu.c @@ -34,7 +34,7 @@ #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/socket_functions.h" -#include "cfw_config.h" +#include "menu.h" #define MAX_CONFIG_SETTINGS_EXPERT 9 #define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)