Add a fsa ioctl to give handles full capabilities

This commit is contained in:
Maschell 2022-07-25 15:14:30 +02:00
parent 224a68531e
commit 47641326a5
15 changed files with 537 additions and 2 deletions

View File

@ -95,12 +95,13 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
$(BUILD): $(CURDIR)/source/ios_kernel/ios_kernel.bin.h $(BUILD): $(CURDIR)/source/ios_kernel/ios_kernel.bin.h
@[ -d $@ ] || mkdir -p $@ @[ -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_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_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 $(CURDIR)/source/ios_kernel -f $(CURDIR)/source/ios_kernel/Makefile
@$(MAKE) -j1 --no-print-directory -C $(BUILD) -f $(CURDIR)/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 @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_kernel -f $(CURDIR)/source/ios_kernel/Makefile
$(CURDIR)/source/ios_usb/ios_usb.bin.h: $(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: $(CURDIR)/source/ios_mcp/ios_mcp.bin.h:
@$(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_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: clean:
@echo 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_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_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_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 else

View File

@ -33,6 +33,7 @@ typedef struct __attribute__((packed)) {
} payload_info_t; } payload_info_t;
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ /* 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_kernel/ios_kernel.bin.h"
#include "ios_mcp/ios_mcp.bin.h" #include "ios_mcp/ios_mcp.bin.h"
#include "ios_usb/ios_usb.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); payloads->size = sizeof(ios_mcp);
memcpy(payloads->data, ios_mcp, payloads->size); 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[33] = 0x500000;
pretend_root_hub[78] = 0; 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) { 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 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 OSSleepTicks(0x200000); //! Improves stability
int request_buffer[] = {-(0xBEA2C), val}; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 int request_buffer[] = {-(0xBEA2C), val}; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
int output_buffer[32]; int output_buffer[32];

4
source/ios_fs/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build/
*.bin
*.bin.h
*.elf

147
source/ios_fs/Makefile Normal file
View File

@ -0,0 +1,147 @@
#-------------------------------------------------------------------------------
.SUFFIXES:
#-------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
#---------------------------------------------------------------------------------
# iosu_rules
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>/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
#---------------------------------------------------------------------------------------

30
source/ios_fs/link.ld Normal file
View File

@ -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");

View File

@ -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

View File

@ -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

118
source/ios_fs/source/main.c Normal file
View File

@ -0,0 +1,118 @@
#include "ipc_types.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
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);
}

View File

@ -0,0 +1,16 @@
#ifndef _TYPES_H
#define _TYPES_H
#include <stdint.h>
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

View File

@ -21,8 +21,10 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include "../../ios_fs/ios_fs_syms.h"
#include "../../ios_mcp/ios_mcp_syms.h" #include "../../ios_mcp/ios_mcp_syms.h"
#include "elf_patcher.h" #include "elf_patcher.h"
#include "ios_fs_patches.h"
#include "ios_mcp_patches.h" #include "ios_mcp_patches.h"
#include "kernel_patches.h" #include "kernel_patches.h"
#include "types.h" #include "types.h"
@ -47,10 +49,21 @@ void instant_patches_setup(void) {
*(volatile u32 *) 0x0812CD2C = ARM_B(0x0812CD2C, kernel_syscall_0x81); *(volatile u32 *) 0x0812CD2C = ARM_B(0x0812CD2C, kernel_syscall_0x81);
// Keep patches for backwards compatibility (libiosuhax)
// patch FSA raw access // patch FSA raw access
*(volatile u32 *) 0x1070FAE8 = 0x05812070; *(volatile u32 *) 0x1070FAE8 = 0x05812070;
*(volatile u32 *) 0x1070FAEC = 0xEAFFFFF9; *(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. // patch /dev/odm IOCTL 0x06 to return the disc key if in_buf[0] > 2.
*(volatile u32 *) 0x10739948 = 0xe3a0b001; // mov r11, 0x01 *(volatile u32 *) 0x10739948 = 0xe3a0b001; // mov r11, 0x01
*(volatile u32 *) 0x1073994C = 0xe3a07020; // mov r7, 0x20 *(volatile u32 *) 0x1073994C = 0xe3a07020; // mov r7, 0x20

View File

@ -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 <string.h>
#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);
}

View File

@ -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 <stdint.h>
uint32_t fs_get_phys_code_base(void);
void fs_run_patches(uint32_t ios_elf_start);
void reset_fs_bss();
#endif

View File

@ -24,6 +24,7 @@
#include "kernel_patches.h" #include "kernel_patches.h"
#include "../../common/kernel_commands.h" #include "../../common/kernel_commands.h"
#include "elf_patcher.h" #include "elf_patcher.h"
#include "ios_fs_patches.h"
#include "ios_mcp_patches.h" #include "ios_mcp_patches.h"
#include "thread.h" #include "thread.h"
#include "types.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 //! try to keep the order of virt. addresses to reduce the memmove amount
mcp_run_patches(ios_elf_start); mcp_run_patches(ios_elf_start);
kernel_run_patches(ios_elf_start); kernel_run_patches(ios_elf_start);
fs_run_patches(ios_elf_start);
restore_mmu(control_register); restore_mmu(control_register);
enable_interrupts(level); enable_interrupts(level);

View File

@ -27,6 +27,7 @@
#include "utils.h" #include "utils.h"
#define USB_PHYS_CODE_BASE 0x101312D0 #define USB_PHYS_CODE_BASE 0x101312D0
#define FS_PHYS_CODE_BASE 0x107F8200
typedef struct { typedef struct {
u32 size; u32 size;
@ -91,6 +92,9 @@ int _main() {
payloads = (payload_info_t *) 0x00160000; payloads = (payload_info_t *) 0x00160000;
kernel_memcpy((void *) mcp_get_phys_code_base(), payloads->data, payloads->size); 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 // run all instant patches as necessary
instant_patches_setup(); instant_patches_setup();

View File

@ -22,6 +22,8 @@
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include <stddef.h>
// this memcpy is optimized for speed and to work with MEM1 32 bit access alignment requirement // 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) { void reverse_memcpy(void *dst, const void *src, unsigned int size) {
const unsigned char *src_p; const unsigned char *src_p;
@ -82,3 +84,13 @@ void reverse_memcpy(void *dst, const void *src, unsigned int size) {
while (size--) while (size--)
*dst_p-- = *src_p--; *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;
}