mirror of
https://github.com/wiiu-env/MochaPayload.git
synced 2024-11-25 09:16:53 +01:00
Add a fsa ioctl to give handles full capabilities
This commit is contained in:
parent
224a68531e
commit
47641326a5
7
Makefile
7
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
|
||||
|
@ -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];
|
||||
|
4
source/ios_fs/.gitignore
vendored
Normal file
4
source/ios_fs/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
build/
|
||||
*.bin
|
||||
*.bin.h
|
||||
*.elf
|
147
source/ios_fs/Makefile
Normal file
147
source/ios_fs/Makefile
Normal 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
30
source/ios_fs/link.ld
Normal 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");
|
11
source/ios_fs/source/hook.s
Normal file
11
source/ios_fs/source/hook.s
Normal 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
|
76
source/ios_fs/source/ipc_types.h
Normal file
76
source/ios_fs/source/ipc_types.h
Normal 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
118
source/ios_fs/source/main.c
Normal 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);
|
||||
}
|
16
source/ios_fs/source/types.h
Normal file
16
source/ios_fs/source/types.h
Normal 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
|
@ -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
|
||||
|
56
source/ios_kernel/source/ios_fs_patches.c
Normal file
56
source/ios_kernel/source/ios_fs_patches.c
Normal 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);
|
||||
}
|
34
source/ios_kernel/source/ios_fs_patches.h
Normal file
34
source/ios_kernel/source/ios_fs_patches.h
Normal 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
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
* distribution.
|
||||
***************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user