diff --git a/.gitignore b/.gitignore index fa8c878..2eab016 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ cmake-build-debug/ .idea/ CMakeLists.txt cmake-build-debug-mocha-builder/ +source/ios_net/ios_net.bin +source/ios_net/ios_net.bin.h diff --git a/Makefile b/Makefile index f87ded8..35be138 100644 --- a/Makefile +++ b/Makefile @@ -96,16 +96,20 @@ $(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_net -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_fs/ios_fs.bin.h +$(CURDIR)/source/ios_kernel/ios_kernel.bin.h: $(CURDIR)/source/ios_usb/ios_usb.bin.h $(CURDIR)/source/ios_net/ios_net.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: @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_usb -f $(CURDIR)/source/ios_usb/Makefile - + +$(CURDIR)/source/ios_net/ios_net.bin.h: + @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_net -f $(CURDIR)/source/ios_net/Makefile + $(CURDIR)/source/ios_mcp/ios_mcp.bin.h: @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/source/ios_mcp -f $(CURDIR)/source/ios_mcp/Makefile @@ -117,6 +121,7 @@ clean: @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf @$(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_net -f $(CURDIR)/source/ios_net/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 diff --git a/source/ios_exploit.c b/source/ios_exploit.c index 4c86d2a..a1c0aa3 100644 --- a/source/ios_exploit.c +++ b/source/ios_exploit.c @@ -36,6 +36,7 @@ typedef struct __attribute__((packed)) { #include "ios_fs/ios_fs.bin.h" #include "ios_kernel/ios_kernel.bin.h" #include "ios_mcp/ios_mcp.bin.h" +#include "ios_net/ios_net.bin.h" #include "ios_usb/ios_usb.bin.h" /* ROP CHAIN STARTS HERE (0x1015BD78) */ @@ -316,11 +317,15 @@ static void uhs_exploit_init(int dev_uhs_0_handle) { static_assert(sizeof(final_chain) < 0xF4148000 - 0xF4140000, "ios_kernel is too big"); memcpy((char *) (0xF4140000), ios_kernel, sizeof(ios_kernel)); - static_assert(sizeof(ios_usb) < 0xF4160000 - 0xF4148000, "IOS_USB is too big"); + static_assert(sizeof(ios_usb) < 0xF4149000 - 0xF4148000, "IOS_USB is too big"); payload_info_t *payloads = (payload_info_t *) 0xF4148000; payloads->size = sizeof(ios_usb); memcpy(payloads->data, ios_usb, payloads->size); + static_assert(sizeof(ios_net) < 0xF4160000 - 0xF4149000, "IOS_NET is too big"); + payloads = (payload_info_t *) 0xF4149000; + payloads->size = sizeof(ios_net); + memcpy(payloads->data, ios_net, payloads->size); static_assert(sizeof(ios_mcp) < 0xF4170000 - 0xF4160000, "IOS_MCP is too big"); payloads = (payload_info_t *) 0xF4160000; diff --git a/source/ios_kernel/source/instant_patches.c b/source/ios_kernel/source/instant_patches.c index 3781c91..b8b4e21 100644 --- a/source/ios_kernel/source/instant_patches.c +++ b/source/ios_kernel/source/instant_patches.c @@ -23,9 +23,9 @@ ***************************************************************************/ #include "../../ios_fs/ios_fs_syms.h" #include "../../ios_mcp/ios_mcp_syms.h" +#include "../../ios_net/ios_net_syms.h" #include "elf_patcher.h" #include "ios_fs_patches.h" -#include "ios_mcp_patches.h" #include "kernel_patches.h" #include "types.h" #include "utils.h" @@ -47,6 +47,7 @@ typedef struct { #define mcp_text_phys(addr) ((u32) (addr) -0x05000000 + 0x081C0000) #define mcp_rodata_phys(addr) ((u32) (addr) -0x05060000 + 0x08220000) #define mcp_data_phys(addr) ((u32) (addr) -0x05074000 + 0x08234000) +#define net_phys(addr) ((u32) (addr)) #define fsa_phys(addr) ((u32) (addr)) #define kernel_phys(addr) ((u32) (addr)) #define acp_text_phys(addr) ((u32) (addr) -0xE0000000 + 0x12900000) @@ -165,6 +166,53 @@ void instant_patches_setup(void) { *(volatile u32 *) mcp_data_phys(0x050B817C) = *(volatile u32 *) 0x0017FFF0; *(volatile u32 *) mcp_data_phys(0x050B8180) = *(volatile u32 *) 0x0017FFF4; + // Patch DLP region check by replacing result code with success + *(volatile u32 *) net_phys(0x1239DA7C) = 0; + + // Patch DLP to ignore error for missing title archive + *(volatile u32 *) net_phys(0x1239E108) = 0xEA000000; // mov r0, r0 + *(volatile u32 *) net_phys(0x1239E10C) = 0xEA000000; // mov r0, r0 + *(volatile u32 *) net_phys(0x1239E110) = 0xEA000000; // mov r0, r0 + + // Patch DLP path from /vol/content/dlp/app to sd:/dlp/app + *(volatile u32 *) net_phys(0x12455368) = 0x2F766F6C; // /vol + *(volatile u32 *) net_phys(0x12455368 + 4) = 0x2F646C70; // /dlp + *(volatile u32 *) net_phys(0x12455368 + 8) = 0x5F5F7364; // __sd + *(volatile u32 *) net_phys(0x12455368 + 12) = 0x2F646C70; // /dlp + *(volatile u32 *) net_phys(0x12455368 + 16) = 0x2F617070; // /app + *(volatile u32 *) net_phys(0x12455368 + 20) = 0x00000000; // + + // Patch DLP path from /vol/content/dlp/app to sd:/dlp/app + *(volatile u32 *) net_phys(0x12455490) = 0x2F766F6C; // /vol + *(volatile u32 *) net_phys(0x12455490 + 4) = 0x2F646C70; // /dlp + *(volatile u32 *) net_phys(0x12455490 + 8) = 0x5F5F7364; // __sd + *(volatile u32 *) net_phys(0x12455490 + 12) = 0x2F646C70; // /dlp + *(volatile u32 *) net_phys(0x12455490 + 16) = 0x2F617070; // /app + *(volatile u32 *) net_phys(0x12455490 + 20) = 0x00000000; // + + // DLP: (un)mount sd card for .cia reading. + *(volatile u32 *) net_phys(0x1237f33c) = ARM_BL(0x1237f33c, DLP_FSAInit_patch); + *(volatile u32 *) net_phys(0x123a4448) = ARM_BL(0x123a4448, DLP_FSAInit_patch); + *(volatile u32 *) net_phys(0x1239de98) = ARM_BL(0x1239de98, DLP_FSAInit_patch); + + *(volatile u32 *) net_phys(0x1237f310) = ARM_BL(0x1237f310, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239dfa0) = ARM_BL(0x1239dfa0, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239dfc0) = ARM_BL(0x1239dfc0, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239dfd8) = ARM_BL(0x1239dfd8, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239dfec) = ARM_BL(0x1239dfec, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239e020) = ARM_BL(0x1239e020, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x1239e094) = ARM_BL(0x1239e094, DLP_FSADeinit_patch); + *(volatile u32 *) net_phys(0x123a457c) = ARM_BL(0x123a457c, DLP_FSADeinit_patch); + + // DLP debug: + /* + *(volatile u32 *) net_phys(0x123a449c) = ARM_BL(0x123a449c, DLP_FSA_OpenFile); + *(volatile u32 *) net_phys(0x1239ce08) = ARM_BL(0x1239ce08, DLP_FSA_OpenFile); + *(volatile u32 *) net_phys(0x1239cf68) = ARM_BL(0x1239cf68, DLP_FSA_OpenFile); + *(volatile u32 *) net_phys(0x1239defc) = ARM_BL(0x1239defc, DLP_FSA_OpenFile); + *(volatile u32 *) net_phys(0x1239debc) = ARM_BL(0x1239debc, DLP_GetChildTitleId); + */ + // Place the environment path at the end of our .text section. for (int i = 0; i < ENVIRONMENT_PATH_LENGTH; i += 4) { *(volatile u32 *) mcp_custom_text_phys(MCP_CUSTOM_TEXT_START + MCP_CUSTOM_TEXT_LENGTH - ENVIRONMENT_PATH_LENGTH + i) = *(volatile u32 *) (0x0017FEF0 + i); diff --git a/source/ios_kernel/source/ios_net_patches.c b/source/ios_kernel/source/ios_net_patches.c new file mode 100644 index 0000000..699cb5c --- /dev/null +++ b/source/ios_kernel/source/ios_net_patches.c @@ -0,0 +1,61 @@ +#include "ios_net_patches.h" +#include "../../ios_net/ios_net_syms.h" +#include "elf_patcher.h" +#include "types.h" + +#define NET_CODE_BASE_PHYS_ADDR (0) + +u32 net_get_phys_code_base(void) { + return _text_start + NET_CODE_BASE_PHYS_ADDR; +} + +void net_run_patches(u32 ios_elf_start) { + section_write(ios_elf_start, _text_start, (void *) net_get_phys_code_base(), _text_end - _text_start); + + // Patch DLP region check by replacing result code with success + section_write_word(ios_elf_start, 0x1239DA7C, 0); + + // Patch DLP to ignore error for missing title archive + section_write_word(ios_elf_start, 0x1239E108, 0xEA000000); // mov r0, r0 + section_write_word(ios_elf_start, 0x1239E10C, 0xEA000000); // mov r0, r0 + section_write_word(ios_elf_start, 0x1239E110, 0xEA000000); // mov r0, r0 + + // Patch DLP path from /vol/content/dlp/app to sd:/dlp/app + section_write_word(ios_elf_start, 0x12455368, 0x2F766F6C); // /vol + section_write_word(ios_elf_start, 0x12455368 + 4, 0x2F646C70); // /dlp + section_write_word(ios_elf_start, 0x12455368 + 8, 0x5F5F7364); // __sd + section_write_word(ios_elf_start, 0x12455368 + 12, 0x2F646C70); // /dlp + section_write_word(ios_elf_start, 0x12455368 + 16, 0x2F617070); // /app + section_write_word(ios_elf_start, 0x12455368 + 20, 0x00000000); // + + // Patch DLP path from /vol/content/dlp/app to sd:/dlp/app + section_write_word(ios_elf_start, 0x12455490, 0x2F766F6C); // /vol + section_write_word(ios_elf_start, 0x12455490 + 4, 0x2F646C70); // /dlp + section_write_word(ios_elf_start, 0x12455490 + 8, 0x5F5F7364); // __sd + section_write_word(ios_elf_start, 0x12455490 + 12, 0x2F646C70); // /dlp + section_write_word(ios_elf_start, 0x12455490 + 16, 0x2F617070); // /app + section_write_word(ios_elf_start, 0x12455490 + 20, 0x00000000); // + + // DLP: (un)mount sd card for .cia reading. + section_write_word(ios_elf_start, 0x1237f33c, ARM_BL(0x1237f33c, DLP_FSAInit_patch)); + section_write_word(ios_elf_start, 0x123a4448, ARM_BL(0x123a4448, DLP_FSAInit_patch)); + section_write_word(ios_elf_start, 0x1239de98, ARM_BL(0x1239de98, DLP_FSAInit_patch)); + + section_write_word(ios_elf_start, 0x1237f310, ARM_BL(0x1237f310, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239dfa0, ARM_BL(0x1239dfa0, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239dfc0, ARM_BL(0x1239dfc0, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239dfd8, ARM_BL(0x1239dfd8, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239dfec, ARM_BL(0x1239dfec, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239e020, ARM_BL(0x1239e020, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x1239e094, ARM_BL(0x1239e094, DLP_FSADeinit_patch)); + section_write_word(ios_elf_start, 0x123a457c, ARM_BL(0x123a457c, DLP_FSADeinit_patch)); + + // DLP debug: + /* + section_write_word(ios_elf_start, 0x123a449c, ARM_BL(0x123a449c, DLP_FSA_OpenFile)); + section_write_word(ios_elf_start, 0x1239ce08, ARM_BL(0x1239ce08, DLP_FSA_OpenFile)); + section_write_word(ios_elf_start, 0x1239cf68, ARM_BL(0x1239cf68, DLP_FSA_OpenFile)); + section_write_word(ios_elf_start, 0x1239defc, ARM_BL(0x1239defc, DLP_FSA_OpenFile)); + section_write_word(ios_elf_start, 0x1239debc, ARM_BL(0x1239debc, DLP_GetChildTitleId)); + */ +} diff --git a/source/ios_kernel/source/ios_net_patches.h b/source/ios_kernel/source/ios_net_patches.h new file mode 100644 index 0000000..a5c1c62 --- /dev/null +++ b/source/ios_kernel/source/ios_net_patches.h @@ -0,0 +1,10 @@ +#ifndef _NET_PATCHES_H_ +#define _NET_PATCHES_H_ + +#include "types.h" + +u32 net_get_phys_code_base(void); + +void net_run_patches(u32 ios_elf_start); + +#endif diff --git a/source/ios_kernel/source/main.c b/source/ios_kernel/source/main.c index 2f1a2d1..d3b858e 100644 --- a/source/ios_kernel/source/main.c +++ b/source/ios_kernel/source/main.c @@ -23,6 +23,7 @@ ***************************************************************************/ #include "instant_patches.h" #include "ios_mcp_patches.h" +#include "ios_net_patches.h" #include "types.h" #include "utils.h" @@ -90,6 +91,9 @@ int _main() { payload_info_t *payloads = (payload_info_t *) 0x00148000; kernel_memcpy((void *) USB_PHYS_CODE_BASE, payloads->data, payloads->size); + payloads = (payload_info_t *) 0x00149000; + kernel_memcpy((void *) net_get_phys_code_base(), payloads->data, payloads->size); + payloads = (payload_info_t *) 0x00160000; kernel_memcpy((void *) mcp_get_phys_code_base(), payloads->data, payloads->size); diff --git a/source/ios_net/Makefile b/source/ios_net/Makefile new file mode 100644 index 0000000..acc5054 --- /dev/null +++ b/source/ios_net/Makefile @@ -0,0 +1,146 @@ +#------------------------------------------------------------------------------- +.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 + +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: $(OUTPUT).elf + @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}' >> $@ + @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_net/imports.ld b/source/ios_net/imports.ld new file mode 100644 index 0000000..2fd978c --- /dev/null +++ b/source/ios_net/imports.ld @@ -0,0 +1,32 @@ +/*PROVIDE(printf = 0x123ccff4); <- this one prints annoying timestamps*/ +PROVIDE(printf = 0x123ccfbc); + +PROVIDE(memcpy = 0x123e2a24); +PROVIDE(memset = 0x123e2ac0); +PROVIDE(strncpy = 0x123e3534); +PROVIDE(snprintf = 0x123e34cc); + +PROVIDE(IOS_CreateThread = 0x123e4254); +PROVIDE(IOS_StartThread = 0x123e428c); +PROVIDE(IOS_GetThreadPriority = 0x123e42a4); +PROVIDE(IOS_CreateMessageQueue = 0x123e42b4); +PROVIDE(IOS_DestroyMessageQueue = 0x123e42bc); +PROVIDE(IOS_ReceiveMessage = 0x123e42d4); +PROVIDE(IOS_Alloc = 0x123e438c); +PROVIDE(IOS_AllocAligned = 0x123e4394); +PROVIDE(IOS_Free = 0x123e439c); +PROVIDE(IOS_Open = 0x123e43ec); +PROVIDE(IOS_Close = 0x123e43f4); +PROVIDE(IOS_Ioctl = 0x123e4414); +PROVIDE(IOS_Ioctlv = 0x123e441c); +PROVIDE(IOS_GetAbsTime64 = 0x123e433c); +PROVIDE(IOS_GetAbsTimeCalendar = 0x123e4334); +PROVIDE(IOS_CreateSemaphore = 0x123e450c); +PROVIDE(IOS_WaitSemaphore = 0x123e4514); +PROVIDE(IOS_SignalSemaphore = 0x123e451c); +PROVIDE(IOS_DestroySemaphore = 0x123e4524); + +PROVIDE(FSA_Mount = 0x123cc44c); +PROVIDE(FSA_Unmount = 0x123cbfb4); +PROVIDE(FSA_OpenDir = 0x123c9f48); +PROVIDE(FSA_CloseDir = 0x123c97b0); diff --git a/source/ios_net/link.ld b/source/ios_net/link.ld new file mode 100644 index 0000000..9cc5da9 --- /dev/null +++ b/source/ios_net/link.ld @@ -0,0 +1,28 @@ +OUTPUT_ARCH(arm) + +INCLUDE "imports.ld" + +SECTIONS { + . = 0x12431900; /* real .text section is ending at 0x12431843, Hokaku is starting at 0x12432000 */ + + .text : { + _text_start = .; + *(.text*); + *(.rodata*); + *(.data*); + } + _text_end = .; + +/* We don't need a .bss section for now. Keep Hokaku in mind when adding .bss section. + .bss : { + _bss_start = .; + *(.bss*); + } + _bss_end = .;*/ + + /DISCARD/ : { + *(*); + } +} + +ASSERT((0x12431900 + SIZEOF(.text)) < 0x12432000, "ios_net text is too big"); diff --git a/source/ios_net/source/fsa.h b/source/ios_net/source/fsa.h new file mode 100644 index 0000000..ca9919c --- /dev/null +++ b/source/ios_net/source/fsa.h @@ -0,0 +1,15 @@ +#ifndef FSA_H +#define FSA_H + +#include + +#define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) +#define FSA_MOUNTFLAGS_GLOBAL (1 << 1) + +int FSA_Mount(int fd, char *device_path, char *volume_path, uint32_t flags, char *arg_string, int arg_string_len); +int FSA_Unmount(int fd, char *path, uint32_t flags); + +int FSA_OpenDir(int fd, char *path, int *outHandle); +int FSA_CloseDir(int fd, int handle); + +#endif diff --git a/source/ios_net/source/ios.h b/source/ios_net/source/ios.h new file mode 100644 index 0000000..de9a38e --- /dev/null +++ b/source/ios_net/source/ios.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +typedef struct { + void *vaddr; + uint32_t len; + uint32_t paddr; +} IOSVec_t; + +typedef struct { + uint32_t year; + uint32_t month; + uint32_t day; + uint32_t hour; + uint32_t minute; + uint32_t second; +} CalendarTime_t; + +#define IOS_HEAP_LOCAL 0xcafe +#define IOS_HEAP_SHARED 0xcaff + +void *IOS_Alloc(uint32_t heap, uint32_t size); + +void *IOS_AllocAligned(uint32_t heap, uint32_t size, uint32_t alignment); + +void IOS_Free(uint32_t heap, void *ptr); + +int IOS_Open(const char *device, int mode); + +int IOS_Close(int fd); + +int IOS_Ioctl(int fd, uint32_t request, void *input_buffer, uint32_t len_in, void *output_buffer, uint32_t len_out); + +int IOS_Ioctlv(int fd, uint32_t request, uint32_t num_in, uint32_t num_out, IOSVec_t *vectors); + +int IOS_GetAbsTime64(uint64_t *time); + +int IOS_GetAbsTimeCalendar(CalendarTime_t *time); + +int IOS_CreateSemaphore(int32_t maxCount, int32_t initialCount); + +int IOS_WaitSemaphore(int id, uint32_t tryWait); + +int IOS_SignalSemaphore(int id); + +int IOS_DestroySemaphore(int id); diff --git a/source/ios_net/source/main.c b/source/ios_net/source/main.c new file mode 100644 index 0000000..04dd219 --- /dev/null +++ b/source/ios_net/source/main.c @@ -0,0 +1,42 @@ +#include "fsa.h" +#include + +uint32_t DLP_FSAInit_patch(void *u1) { + int (*const real_DLP_FSAInit_patch)(void *) = (void *) 0x0123c0a1c; + int handle = real_DLP_FSAInit_patch(u1); + if (handle != -1) { + if (FSA_Mount(handle, "/dev/sdcard01", "/vol/dlp__sd", 0, 0, 0) == 0) { + printf("Mocha (DLP): Mounted sd card for handle (%08X).\n", handle); + } else { + printf("Mocha (DLP): Failed to mount sd card for handle (%08X).\n", handle); + } + } else { + printf("Mocha (DLP): Getting FSAClient failed. Could not mount sd card.\n"); + } + return handle; +} + +uint32_t DLP_FSADeinit_patch(int fsaHandle) { + uint32_t (*const real_NET_DLP_deinit_patch)(int) = (void *) 0x123c0948; + if (FSA_Unmount(fsaHandle, "/vol/dlp__sd", 0) == 0) { + printf("Mocha (DLP): Unmounted sd card for handle (%08X).\n", fsaHandle); + } else { + printf("Mocha (DLP): Failed to unmount sd card for handle (%08X).\n", fsaHandle); + } + return real_NET_DLP_deinit_patch(fsaHandle); +} + + +uint32_t DLP_FSA_OpenFile(int fd, char *path, char *mode, uint32_t *outhandle) { + int (*const real_DLP_FSA_OpenFile)(int, char *, char *, uint32_t *) = (void *) 0x123c9480; + int result = real_DLP_FSA_OpenFile(fd, path, mode, outhandle); + printf("DLP_FSA_OpenFile(%08X %s %s %p) returned %d \n", fd, path, mode, outhandle, result); + return result; +} + +uint32_t DLP_GetChildTitleId(uint32_t *titleId, uint32_t uniqueId, int fsaHandle, const char *path, uint8_t childIndex) { + int (*const real_DLP_GetChildTitleId)(uint32_t * titleId, uint32_t uniqueId, int fsaHandle, const char *, uint8_t childIndex) = (void *) 0x1239bd38; + int result = real_DLP_GetChildTitleId(titleId, uniqueId, fsaHandle, path, childIndex); + printf("DLP_GetChildTitleId(%08X%08X unique %08X handle %08X path \"%s\" childindex %02X) returned %d \n", titleId[0], titleId[1], uniqueId, fsaHandle, path, childIndex, result); + return result; +}