From 43f1af08a345b333e800ac1e2e18e7aa153e9da9 Mon Sep 17 00:00:00 2001 From: dimok789 Date: Tue, 7 Feb 2017 18:15:16 +0100 Subject: [PATCH] wip commit of the FAT32 nativ USB support NOTE: This is a work in progress commit. It includes debug and test functions and some features that existed before might not even work. It is not finished and not very well tested. So it's warning to NOT use this for everyday playing! This is target for developers to look some stuff up that I was working on. See also my post on gbatemp for more information. --- .gitignore | 7 +- Makefile | 6 +- common/config_types.h | 40 ++++ common/kernel_commands.h | 32 +++ ios_acp/Makefile | 80 ++++++++ ios_acp/link.ld | 23 +++ ios_acp/source/imports.h | 7 + ios_acp/source/main.c | 41 ++++ ios_acp/source/types.h | 29 +++ ios_fs/source/devices.h | 56 +++++- ios_fs/source/dumper.c | 3 +- ios_fs/source/fsa.c | 222 +++++++++++++++++++++ ios_fs/source/fsa.h | 42 ++++ ios_fs/source/function_hooks.s | 13 +- ios_fs/source/imports.h | 8 +- ios_fs/source/main.c | 62 ++++-- ios_fs/source/svc.h | 2 +- ios_fs/source/svc.s | 6 +- ios_kernel/source/config.h | 2 +- ios_kernel/source/elf_patcher.h | 6 +- ios_kernel/source/ios_acp_patches.c | 59 ++++++ ios_kernel/source/ios_acp_patches.h | 30 +++ ios_kernel/source/ios_acp_patches_asm.s | 11 ++ ios_kernel/source/ios_fs_patches.c | 38 +++- ios_kernel/source/ios_mcp_patches.c | 7 +- ios_kernel/source/ios_mcp_patches_asm.s | 7 + ios_kernel/source/kernel_patches.c | 45 ++++- ios_kernel/source/main.c | 19 +- ios_kernel/source/utils.h | 5 + ios_mcp/link.ld | 2 +- ios_mcp/source/ipc.c | 121 +++++++----- ios_mcp/source/ipc.h | 1 + ios_mcp/source/main.c | 235 +--------------------- ios_mcp/source/socket.c | 14 ++ ios_mcp/source/svc.h | 3 +- ios_mcp/source/svc.s | 12 +- ios_mcp/source/wupserver.c | 250 ++++++++++++++++++++++++ ios_mcp/source/wupserver.h | 7 + ios_mcp/wupclient.py | 2 +- src/cfw_config.h | 13 +- src/fs/fs_utils.c | 2 + src/ios_exploit.c | 58 +++--- src/menu.c | 2 +- 43 files changed, 1242 insertions(+), 388 deletions(-) create mode 100644 common/config_types.h create mode 100644 common/kernel_commands.h create mode 100644 ios_acp/Makefile create mode 100644 ios_acp/link.ld create mode 100644 ios_acp/source/imports.h create mode 100644 ios_acp/source/main.c create mode 100644 ios_acp/source/types.h create mode 100644 ios_fs/source/fsa.c create mode 100644 ios_fs/source/fsa.h create mode 100644 ios_kernel/source/ios_acp_patches.c create mode 100644 ios_kernel/source/ios_acp_patches.h create mode 100644 ios_kernel/source/ios_acp_patches_asm.s create mode 100644 ios_mcp/source/wupserver.c create mode 100644 ios_mcp/source/wupserver.h 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)