From 47641326a5dcaf64ead933fbdcd6064110210db3 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 25 Jul 2022 15:14:30 +0200 Subject: [PATCH] Add a fsa ioctl to give handles full capabilities --- Makefile | 7 +- source/ios_exploit.c | 9 +- source/ios_fs/.gitignore | 4 + source/ios_fs/Makefile | 147 +++++++++++++++++++++ source/ios_fs/link.ld | 30 +++++ source/ios_fs/source/hook.s | 11 ++ source/ios_fs/source/ipc_types.h | 76 +++++++++++ source/ios_fs/source/main.c | 118 +++++++++++++++++ source/ios_fs/source/types.h | 16 +++ source/ios_kernel/source/instant_patches.c | 13 ++ source/ios_kernel/source/ios_fs_patches.c | 56 ++++++++ source/ios_kernel/source/ios_fs_patches.h | 34 +++++ source/ios_kernel/source/kernel_patches.c | 2 + source/ios_kernel/source/main.c | 4 + source/ios_kernel/source/utils.c | 12 ++ 15 files changed, 537 insertions(+), 2 deletions(-) create mode 100644 source/ios_fs/.gitignore create mode 100644 source/ios_fs/Makefile create mode 100644 source/ios_fs/link.ld create mode 100644 source/ios_fs/source/hook.s create mode 100644 source/ios_fs/source/ipc_types.h create mode 100644 source/ios_fs/source/main.c create mode 100644 source/ios_fs/source/types.h create mode 100644 source/ios_kernel/source/ios_fs_patches.c create mode 100644 source/ios_kernel/source/ios_fs_patches.h diff --git a/Makefile b/Makefile index b6c1348..5f38c3a 100644 --- a/Makefile +++ b/Makefile @@ -95,12 +95,13 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) #------------------------------------------------------------------------------- $(BUILD): $(CURDIR)/source/ios_kernel/ios_kernel.bin.h @[ -d $@ ] || mkdir -p $@ + @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_fs -f $(CURDIR)/source/ios_fs/Makefile @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_mcp -f $(CURDIR)/source/ios_mcp/Makefile @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_usb -f $(CURDIR)/source/ios_usb/Makefile @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_kernel -f $(CURDIR)/source/ios_kernel/Makefile @$(MAKE) -j1 --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile -$(CURDIR)/source/ios_kernel/ios_kernel.bin.h: $(CURDIR)/source/ios_usb/ios_usb.bin.h $(CURDIR)/source/ios_mcp/ios_mcp.bin.h +$(CURDIR)/source/ios_kernel/ios_kernel.bin.h: $(CURDIR)/source/ios_usb/ios_usb.bin.h $(CURDIR)/source/ios_mcp/ios_mcp.bin.h $(CURDIR)/source/ios_fs/ios_fs.bin.h @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_kernel -f $(CURDIR)/source/ios_kernel/Makefile $(CURDIR)/source/ios_usb/ios_usb.bin.h: @@ -108,6 +109,9 @@ $(CURDIR)/source/ios_usb/ios_usb.bin.h: $(CURDIR)/source/ios_mcp/ios_mcp.bin.h: @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_mcp -f $(CURDIR)/source/ios_mcp/Makefile + +$(CURDIR)/source/ios_fs/ios_fs.bin.h: + @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_fs -f $(CURDIR)/source/ios_fs/Makefile #------------------------------------------------------------------------------- clean: @echo clean ... @@ -115,6 +119,7 @@ clean: @$(MAKE) --no-print-directory -C $(CURDIR)/source/ios_kernel -f $(CURDIR)/source/ios_kernel/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/source/ios_usb -f $(CURDIR)/source/ios_usb/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/source/ios_mcp -f $(CURDIR)/source/ios_mcp/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/source/ios_fs -f $(CURDIR)/source/ios_fs/Makefile clean #------------------------------------------------------------------------------- else diff --git a/source/ios_exploit.c b/source/ios_exploit.c index 0ed74d2..90d9059 100644 --- a/source/ios_exploit.c +++ b/source/ios_exploit.c @@ -33,6 +33,7 @@ typedef struct __attribute__((packed)) { } payload_info_t; /* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ +#include "ios_fs/ios_fs.bin.h" #include "ios_kernel/ios_kernel.bin.h" #include "ios_mcp/ios_mcp.bin.h" #include "ios_usb/ios_usb.bin.h" @@ -326,6 +327,12 @@ static void uhs_exploit_init(int dev_uhs_0_handle) { payloads->size = sizeof(ios_mcp); memcpy(payloads->data, ios_mcp, payloads->size); + + static_assert(sizeof(ios_mcp) < 0xF4180000 - 0xF4170000, "IOS_FS is too big"); + payloads = (payload_info_t *) 0xF4170000; + payloads->size = sizeof(ios_fs); + memcpy(payloads->data, ios_fs, payloads->size); + pretend_root_hub[33] = 0x500000; pretend_root_hub[78] = 0; @@ -338,7 +345,7 @@ static void uhs_exploit_init(int dev_uhs_0_handle) { static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) { ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes - DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) + DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated address) OSSleepTicks(0x200000); //! Improves stability int request_buffer[] = {-(0xBEA2C), val}; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int output_buffer[32]; diff --git a/source/ios_fs/.gitignore b/source/ios_fs/.gitignore new file mode 100644 index 0000000..19ee97e --- /dev/null +++ b/source/ios_fs/.gitignore @@ -0,0 +1,4 @@ +build/ +*.bin +*.bin.h +*.elf diff --git a/source/ios_fs/Makefile b/source/ios_fs/Makefile new file mode 100644 index 0000000..b51abea --- /dev/null +++ b/source/ios_fs/Makefile @@ -0,0 +1,147 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) + +#--------------------------------------------------------------------------------- +# iosu_rules +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=/devkitARM") +endif + +include $(DEVKITARM)/base_rules +export OBJDUMP := $(PREFIX)objdump + +MACHDEP = -DSTARBUCK -mbig-endian -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft + +%.elf: + @echo linking ... $(notdir $@) + $(SILENTCMD)$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ +#--------------------------------------------------------------------------------- + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := source + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -Wall -std=gnu11 -Os $(MACHDEP) $(INCLUDE) -Wno-array-bounds -fno-builtin + +ASFLAGS := $(MACHDEP) + +LDFLAGS := -nostartfiles -nodefaultlibs -mbig-endian \ + -Wl,-L $(TOPDIR) -Wl,-Map,$(notdir $*.map),-T $(TOPDIR)/link.ld -flto + +LIBS := -lgcc + +#------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level +# containing include and lib +#------------------------------------------------------------------------------- +LIBDIRS := + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export TARGETNAME := $(TARGET) + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +export LD := $(CC) + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(SFILES:.s=.o) $(CFILES:.c=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean all +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).bin $(TARGET).bin.h $(TARGET)_syms.h + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +all : $(OUTPUT).bin.h $(OUTPUT)_syms.h + +$(OUTPUT).elf : $(OFILES) + +$(OUTPUT).bin: $(OUTPUT).elf + @echo "built ... $(notdir $@)" + @$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(OUTPUT).elf $@ + +$(OUTPUT).bin.h: $(OUTPUT).bin + @raw2c $< + @cp $(TARGETNAME).c $@ + +$(OUTPUT)_syms.h: + @echo "#ifndef $(TARGETNAME)_SYMS_H" > $@ + @echo "#define $(TARGETNAME)_SYMS_H" >> $@ + @$(OBJDUMP) -EB -t -marm $(OUTPUT).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@ + @$(OBJDUMP) -EB -t -marm $(OUTPUT).elf | grep -e 'g .text' -e '_bss_' | awk '{print "#define " $$5 " 0x" $$1}' >> $@ + @$(OBJDUMP) -EB -t -marm $(OUTPUT).elf | grep 'g O .fn_hook_bufs' | awk '{print "#define " $$6 " 0x" $$1}' >> $@ + @echo "#endif" >> $@ + +$(OFILES_SRC) : $(HFILES_BIN) + +#------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/source/ios_fs/link.ld b/source/ios_fs/link.ld new file mode 100644 index 0000000..1a4afc5 --- /dev/null +++ b/source/ios_fs/link.ld @@ -0,0 +1,30 @@ +OUTPUT_ARCH(arm) + +PROVIDE(printf = 0x107f0c84); + +SECTIONS +{ + .text (0x10700000 + 0x000F8200) : { + _text_start = .; + *(.text*); + *(.rodata*); + } + _text_end = .; + + .bss (0x10835000 + 0x1406554) : { + _bss_start = .; + *(.bss*); + *(COMMON); + } + .io_buffer : ALIGN(0x40) { + *(.io_buffer*); + } + _bss_end = .; + + /DISCARD/ : { + *(*); + } +} + +ASSERT((SIZEOF(.text)) < 0x7E00, "FS text section is too big"); +ASSERT((SIZEOF(.bss)) < 0x2C4AAC, "FS bss section is too big"); diff --git a/source/ios_fs/source/hook.s b/source/ios_fs/source/hook.s new file mode 100644 index 0000000..9cec042 --- /dev/null +++ b/source/ios_fs/source/hook.s @@ -0,0 +1,11 @@ +.arm + +.extern FSA_ioctl0x28_hook + +.global _FSA_ioctl0x28_hook +_FSA_ioctl0x28_hook: + mov r0, r10 + mov r1, r11 + bl FSA_ioctl0x28_hook + mov r5,#0x0 + ldr pc, =0x10701194 diff --git a/source/ios_fs/source/ipc_types.h b/source/ios_fs/source/ipc_types.h new file mode 100644 index 0000000..d89fe05 --- /dev/null +++ b/source/ios_fs/source/ipc_types.h @@ -0,0 +1,76 @@ +#ifndef _IPC_TYPES_H_ +#define _IPC_TYPES_H_ + +#include "types.h" + +#define IOS_COMMAND_INVALID 0x00 +#define IOS_OPEN 0x01 +#define IOS_CLOSE 0x02 +#define IOS_READ 0x03 +#define IOS_WRITE 0x04 +#define IOS_SEEK 0x05 +#define IOS_IOCTL 0x06 +#define IOS_IOCTLV 0x07 +#define IOS_REPLY 0x08 +#define IOS_IPC_MSG0 0x09 +#define IOS_IPC_MSG1 0x0A +#define IOS_IPC_MSG2 0x0B +#define IOS_SUSPEND 0x0C +#define IOS_RESUME 0x0D +#define IOS_SVCMSG 0x0E + + +/* IPC message */ +typedef struct ipcmessage { + u32 command; + u32 result; + u32 fd; + u32 flags; + u32 client_cpu; + u32 client_pid; + u64 client_gid; + u32 server_handle; + + union { + u32 args[5]; + + struct { + char *device; + u32 mode; + u32 resultfd; + } open; + + struct { + void *data; + u32 length; + } read, write; + + struct { + s32 offset; + s32 origin; + } seek; + + struct { + u32 command; + + u32 *buffer_in; + u32 length_in; + u32 *buffer_io; + u32 length_io; + } ioctl; + struct _ioctlv { + u32 command; + + u32 num_in; + u32 num_io; + struct _ioctlv *vector; + } ioctlv; + }; + + u32 prev_command; + u32 prev_fd; + u32 virt0; + u32 virt1; +} __attribute__((packed)) ipcmessage; + +#endif diff --git a/source/ios_fs/source/main.c b/source/ios_fs/source/main.c new file mode 100644 index 0000000..0a4dffb --- /dev/null +++ b/source/ios_fs/source/main.c @@ -0,0 +1,118 @@ +#include "ipc_types.h" +#include +#include +#include + +typedef struct __attribute__((packed)) { + uint32_t initialized; + uint64_t titleId; + uint32_t processId; + uint32_t groupId; + uint32_t unk0; + uint64_t capabilityMask; + uint8_t unk1[0x4518]; + char unk2[0x280]; + char unk3[0x280]; + void *mutex; +} FSAProcessData; +static_assert(sizeof(FSAProcessData) == 0x4A3C, "FSAProcessData: wrong size"); + +typedef struct __attribute__((packed)) { + uint32_t opened; + FSAProcessData *processData; + char unk0[0x10]; + char unk1[0x90]; + uint32_t unk2; + char work_dir[0x280]; + uint32_t unk3; +} FSAClientHandle; +static_assert(sizeof(FSAClientHandle) == 0x330, "FSAClientHandle: wrong size"); + +#define PATCHED_CLIENT_HANDLES_MAX_COUNT 0x40 + +FSAClientHandle *patchedClientHandles[PATCHED_CLIENT_HANDLES_MAX_COUNT]; + +int (*const IOS_ResourceReply)(void *, int32_t) = (void *) 0x107f6b4c; + +int FSA_ioctl0x28_hook(FSAClientHandle *handle, void *request) { + int res = -5; + for (int i = 0; i < PATCHED_CLIENT_HANDLES_MAX_COUNT; i++) { + if (patchedClientHandles[i] == handle) { + res = 0; + break; + } + if (patchedClientHandles[i] == 0) { + patchedClientHandles[i] = handle; + res = 0; + break; + } + } + + IOS_ResourceReply(request, res); + return 0; +} + +typedef struct __attribute__((packed)) { + ipcmessage ipcmessage; +} ResourceRequest; + +int (*const real_FSA_IOCTLV)(ResourceRequest *, uint32_t, uint32_t) = (void *) 0x10703164; +int (*const get_handle_from_val)(uint32_t) = (void *) 0x107046d4; +int FSA_IOCTLV_HOOK(ResourceRequest *param_1, uint32_t u2, uint32_t u3) { + FSAClientHandle *clientHandle = (FSAClientHandle *) get_handle_from_val(param_1->ipcmessage.fd); + uint64_t oldValue = clientHandle->processData->capabilityMask; + int toBeRestored = 0; + for (int i = 0; i < PATCHED_CLIENT_HANDLES_MAX_COUNT; i++) { + if (patchedClientHandles[i] == clientHandle) { + clientHandle->processData->capabilityMask = 0xffffffffffffffffL; + // printf("IOCTL: Force mask to 0xFFFFFFFFFFFFFFFF for client %08X\n", (uint32_t) clientHandle); + toBeRestored = 1; + break; + } + } + int res = real_FSA_IOCTLV(param_1, u2, u3); + + if (toBeRestored) { + // printf("IOCTL: Restore mask for client %08X\n", (uint32_t) clientHandle); + clientHandle->processData->capabilityMask = oldValue; + } + + return res; +} + +int (*const real_FSA_IOCTL)(ResourceRequest *, uint32_t, uint32_t, uint32_t) = (void *) 0x107010a8; + +int FSA_IOCTL_HOOK(ResourceRequest *request, uint32_t u2, uint32_t u3, uint32_t u4) { + FSAClientHandle *clientHandle = (FSAClientHandle *) get_handle_from_val(request->ipcmessage.fd); + uint64_t oldValue = clientHandle->processData->capabilityMask; + int toBeRestored = 0; + for (int i = 0; i < PATCHED_CLIENT_HANDLES_MAX_COUNT; i++) { + if (patchedClientHandles[i] == clientHandle) { + // printf("IOCTL: Force mask to 0xFFFFFFFFFFFFFFFF for client %08X\n", (uint32_t) clientHandle); + clientHandle->processData->capabilityMask = 0xffffffffffffffffL; + toBeRestored = 1; + break; + } + } + int res = real_FSA_IOCTL(request, u2, u3, u4); + + if (toBeRestored) { + // printf("IOCTL: Restore mask for client %08X\n", (uint32_t) clientHandle); + clientHandle->processData->capabilityMask = oldValue; + } + + return res; +} + +int (*const real_FSA_IOS_Close)(uint32_t fd, ResourceRequest *request) = (void *) 0x10704864; +int FSA_IOS_Close_Hook(uint32_t fd, ResourceRequest *request) { + FSAClientHandle *clientHandle = (FSAClientHandle *) get_handle_from_val(fd); + for (int i = 0; i < PATCHED_CLIENT_HANDLES_MAX_COUNT; i++) { + if (patchedClientHandles[i] == clientHandle) { + // printf("Close: %p will be closed, reset slot %d\n", clientHandle, i); + patchedClientHandles[i] = 0; + break; + } + } + return real_FSA_IOS_Close(fd, request); +} \ No newline at end of file diff --git a/source/ios_fs/source/types.h b/source/ios_fs/source/types.h new file mode 100644 index 0000000..5d8eced --- /dev/null +++ b/source/ios_fs/source/types.h @@ -0,0 +1,16 @@ +#ifndef _TYPES_H +#define _TYPES_H + +#include + +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; + +#endif diff --git a/source/ios_kernel/source/instant_patches.c b/source/ios_kernel/source/instant_patches.c index 07d5bd7..09c06b8 100644 --- a/source/ios_kernel/source/instant_patches.c +++ b/source/ios_kernel/source/instant_patches.c @@ -21,8 +21,10 @@ * 3. This notice may not be removed or altered from any source * distribution. ***************************************************************************/ +#include "../../ios_fs/ios_fs_syms.h" #include "../../ios_mcp/ios_mcp_syms.h" #include "elf_patcher.h" +#include "ios_fs_patches.h" #include "ios_mcp_patches.h" #include "kernel_patches.h" #include "types.h" @@ -47,10 +49,21 @@ void instant_patches_setup(void) { *(volatile u32 *) 0x0812CD2C = ARM_B(0x0812CD2C, kernel_syscall_0x81); + // Keep patches for backwards compatibility (libiosuhax) // patch FSA raw access *(volatile u32 *) 0x1070FAE8 = 0x05812070; *(volatile u32 *) 0x1070FAEC = 0xEAFFFFF9; + // Add IOCTL 0x28 to indicate the calling client should have full fs permissions + *(volatile u32 *) 0x10701248 = _FSA_ioctl0x28_hook; + + // Give clients that called IOCTL 0x28 full permissions + *(volatile u32 *) 0x10704540 = ARM_BL(0x10704540, FSA_IOCTLV_HOOK); + *(volatile u32 *) 0x107044f0 = ARM_BL(0x107044f0, FSA_IOCTL_HOOK); + *(volatile u32 *) 0x10704458 = ARM_BL(0x10704458, FSA_IOS_Close_Hook); + + reset_fs_bss(); + // patch /dev/odm IOCTL 0x06 to return the disc key if in_buf[0] > 2. *(volatile u32 *) 0x10739948 = 0xe3a0b001; // mov r11, 0x01 *(volatile u32 *) 0x1073994C = 0xe3a07020; // mov r7, 0x20 diff --git a/source/ios_kernel/source/ios_fs_patches.c b/source/ios_kernel/source/ios_fs_patches.c new file mode 100644 index 0000000..da2fbe6 --- /dev/null +++ b/source/ios_kernel/source/ios_fs_patches.c @@ -0,0 +1,56 @@ +/*************************************************************************** +* 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 "ios_fs_patches.h" +#include "../../ios_fs/ios_fs_syms.h" +#include "elf_patcher.h" +#include "types.h" +#include + +#define FS_PHYS_DIFF 0 + +u32 fs_get_phys_code_base(void) { + return _text_start + FS_PHYS_DIFF; +} + +void reset_fs_bss() { + memset((void *) _bss_start, 0, _bss_end - _bss_start); +} + +void fs_run_patches(uint32_t ios_elf_start) { + section_write(ios_elf_start, _text_start, (void *) fs_get_phys_code_base(), _text_end - _text_start); + section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start); + + // Add IOCTL 0x28 to indicate the calling client should have full fs permissions + section_write_word(ios_elf_start, 0x10701248, _FSA_ioctl0x28_hook); + + // Give clients that called IOCTL 0x28 full permissions + section_write_word(ios_elf_start, 0x10704540, ARM_BL(0x10704540, FSA_IOCTLV_HOOK)); + section_write_word(ios_elf_start, 0x107044f0, ARM_BL(0x107044f0, FSA_IOCTL_HOOK)); + section_write_word(ios_elf_start, 0x10704458, ARM_BL(0x10704458, FSA_IOS_Close_Hook)); + + // Keep patches for backwards compatibility (libiosuhax) + // patch FSA raw access + section_write_word(ios_elf_start, 0x1070FAE8, 0x05812070); + section_write_word(ios_elf_start, 0x1070FAEC, 0xEAFFFFF9); +} \ No newline at end of file diff --git a/source/ios_kernel/source/ios_fs_patches.h b/source/ios_kernel/source/ios_fs_patches.h new file mode 100644 index 0000000..8935ae2 --- /dev/null +++ b/source/ios_kernel/source/ios_fs_patches.h @@ -0,0 +1,34 @@ +/*************************************************************************** +* 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 _FS_PATCHES_H_ +#define _FS_PATCHES_H_ + +#include + +uint32_t fs_get_phys_code_base(void); +void fs_run_patches(uint32_t ios_elf_start); + +void reset_fs_bss(); + +#endif \ No newline at end of file diff --git a/source/ios_kernel/source/kernel_patches.c b/source/ios_kernel/source/kernel_patches.c index 82c6d0e..7293ce3 100644 --- a/source/ios_kernel/source/kernel_patches.c +++ b/source/ios_kernel/source/kernel_patches.c @@ -24,6 +24,7 @@ #include "kernel_patches.h" #include "../../common/kernel_commands.h" #include "elf_patcher.h" +#include "ios_fs_patches.h" #include "ios_mcp_patches.h" #include "thread.h" #include "types.h" @@ -101,6 +102,7 @@ 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); restore_mmu(control_register); enable_interrupts(level); diff --git a/source/ios_kernel/source/main.c b/source/ios_kernel/source/main.c index 095a734..eac1c6b 100644 --- a/source/ios_kernel/source/main.c +++ b/source/ios_kernel/source/main.c @@ -27,6 +27,7 @@ #include "utils.h" #define USB_PHYS_CODE_BASE 0x101312D0 +#define FS_PHYS_CODE_BASE 0x107F8200 typedef struct { u32 size; @@ -91,6 +92,9 @@ int _main() { payloads = (payload_info_t *) 0x00160000; kernel_memcpy((void *) mcp_get_phys_code_base(), payloads->data, payloads->size); + payloads = (payload_info_t *) 0x00170000; + kernel_memcpy((void *) FS_PHYS_CODE_BASE, payloads->data, payloads->size); + // run all instant patches as necessary instant_patches_setup(); diff --git a/source/ios_kernel/source/utils.c b/source/ios_kernel/source/utils.c index a1b1b42..47e0e61 100644 --- a/source/ios_kernel/source/utils.c +++ b/source/ios_kernel/source/utils.c @@ -22,6 +22,8 @@ * distribution. ***************************************************************************/ +#include + // this memcpy is optimized for speed and to work with MEM1 32 bit access alignment requirement void reverse_memcpy(void *dst, const void *src, unsigned int size) { const unsigned char *src_p; @@ -82,3 +84,13 @@ void reverse_memcpy(void *dst, const void *src, unsigned int size) { while (size--) *dst_p-- = *src_p--; } + +void *memset(void *dst, int val, size_t size) { + char *_dst = dst; + + int i; + for (i = 0; i < size; i++) + _dst[i] = val; + + return dst; +} \ No newline at end of file