wip commit of the FAT32 nativ USB support

NOTE:
This is a work in progress commit. It includes debug and test functions and some features that existed before might not even work. It is not finished and not very well tested. So it's warning to NOT use this for everyday playing! This is target for developers to look some stuff up that I was working on. See also my post on gbatemp for more information.
This commit is contained in:
dimok789 2017-02-07 18:15:16 +01:00
parent fe9c3f8434
commit 43f1af08a3
43 changed files with 1242 additions and 388 deletions

7
.gitignore vendored
View File

@ -24,4 +24,9 @@
/ios_usb/ios_usb.bin.h /ios_usb/ios_usb.bin.h
/ios_usb/*.elf /ios_usb/*.elf
/ios_usb/ios_usb_syms.h /ios_usb/ios_usb_syms.h
/ios_usb/build /ios_usb/build
/ios_acp/build
/ios_acp/*.bin
/ios_acp/ios_acp.bin.h
/ios_acp/*.elf
/ios_acp/ios_acp_syms.h

View File

@ -123,7 +123,7 @@ $(BUILD): $(CURDIR)/ios_kernel/ios_kernel.bin.h
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_fs/ios_fs.bin.h $(CURDIR)/ios_bsp/ios_bsp.bin.h $(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_fs/ios_fs.bin.h $(CURDIR)/ios_bsp/ios_bsp.bin.h $(CURDIR)/ios_acp/ios_acp.bin.h
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile
$(CURDIR)/ios_usb/ios_usb.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h:
@ -137,6 +137,9 @@ $(CURDIR)/ios_bsp/ios_bsp.bin.h:
$(CURDIR)/ios_mcp/ios_mcp.bin.h: $(CURDIR)/ios_mcp/ios_mcp.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile @$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile
$(CURDIR)/ios_acp/ios_acp.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@ -147,6 +150,7 @@ clean:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile clean
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

40
common/config_types.h Normal file
View File

@ -0,0 +1,40 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _CONFIG_TYPES_H_
#define _CONFIG_TYPES_H_
typedef struct
{
int viewMode;
int directLaunch;
int launchImage;
int noIosReload;
int launchSysMenu;
int redNAND;
int seeprom_red;
int otp_red;
int syshaxXml;
} cfw_config_t;
#endif

32
common/kernel_commands.h Normal file
View File

@ -0,0 +1,32 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef KERNEL_COMMANDS_H_
#define KERNEL_COMMANDS_H_
#define KERNEL_READ32 1
#define KERNEL_WRITE32 2
#define KERNEL_MEMCPY 3
#define KERNEL_GET_CFW_CONFIG 4
#endif

80
ios_acp/Makefile Normal file
View File

@ -0,0 +1,80 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
export PATH:=$(DEVKITARM)/bin:$(PATH)
endif
CC = arm-none-eabi-gcc
LINK = arm-none-eabi-gcc
AS = arm-none-eabi-as
OBJCOPY = arm-none-eabi-objcopy
OBJDUMP = arm-none-eabi-objdump
CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os
LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld
LIBDIRS += -L$(CURDIR)/../libs
LIBS += -lgcc
CFILES = $(wildcard source/*.c)
BINFILES = $(wildcard data/*.bin)
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
OFILES += $(CFILES:source/%.c=build/%.o)
DFILES = $(CFILES:source/%.c=build/%.d)
SFILES = $(wildcard source/*.s)
OFILES += $(SFILES:source/%.s=build/%.o)
PROJECTNAME = ${shell basename "$(CURDIR)"}
CWD = "$(CURDIR)""
#---------------------------------------------------------------------------------
# canned command sequence for binary data, taken from devkitARM
#---------------------------------------------------------------------------------
define bin2o
bin2s $< | $(AS) -EB -o $(@)
endef
.PHONY:=all dirs
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
dirs:
@mkdir -p build
$(PROJECTNAME).elf: $(OFILES)
@echo "LD $@"
@$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS)
$(PROJECTNAME).bin: $(PROJECTNAME).elf
@echo "OBJCOPY $@\n"
@$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@
$(PROJECTNAME).bin.h: $(PROJECTNAME).bin
@xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
$(PROJECTNAME)_syms.h:
@echo "#ifndef $(PROJECTNAME)_SYMS_H" > $@
@echo "#define $(PROJECTNAME)_SYMS_H" >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' -e "_seeprom_buffer_start" | awk '{print "#define " $$5 " 0x" $$1}' >> $@
@echo "#endif" >> $@
clean:
@rm -f build/*.o build/*.d
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
@echo "all cleaned up !"
-include $(DFILES)
build/%.o: source/%.c
@echo "CC $(notdir $<)"
@$(CC) $(CFLAGS) -c $< -o $@
@$(CC) -MM $< > build/$*.d
build/%.o: source/%.s
@echo "CC $(notdir $<)"
@$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
@$(CC) -MM $< > build/$*.d
build/%.bin.o: data/%.bin
@echo "BIN $(notdir $<)"
@$(bin2o)

23
ios_acp/link.ld Normal file
View File

@ -0,0 +1,23 @@
OUTPUT_ARCH(arm)
SECTIONS
{
.text 0xE00DB660 : {
_text_start = .;
*(.text*);
*(.rodata*);
}
_text_end = .;
.bss 0xE0261F10 : {
_bss_start = .;
*(.bss*);
*(.data*);
}
_bss_end = .;
/DISCARD/ : {
*(*);
}
}

7
ios_acp/source/imports.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _IMPORTS_H_
#define _IMPORTS_H_
#define ACP_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0xE00C4D54)
#endif

41
ios_acp/source/main.c Normal file
View File

@ -0,0 +1,41 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "types.h"
int ACP_FSARawRead_hook(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle)
{
int (*ACP_FSARawRead)(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle) = (void*)0xE00BAF74;
int res = ACP_FSARawRead(fd, data, offset, cnt, blocksize, device_handle);
//! the PPC side has a way to check for a PC or WFS formatted drive by checking the MBR signature
//! it's the only place where this is used so we can just fake it with wrong values.
u8 *buf = (u8*)data;
if((offset == 0) && (buf[510] == 0x55) && (buf[511] == 0xAA))
{
buf[510] = 0xB3;
buf[511] = 0xDE;
}
return res;
}

29
ios_acp/source/types.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdint.h>
#include <stdbool.h>
#define U64_MAX UINT64_MAX
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
#endif

View File

@ -1,8 +1,6 @@
#ifndef DEVICES_H_ #ifndef DEVICES_H_
#define DEVICES_H_ #define DEVICES_H_
#define DEVICE_TYPE_SDCARD 0x06
#define DEVICE_ID_SDCARD_REAL 0x43 #define DEVICE_ID_SDCARD_REAL 0x43
#define DEVICE_ID_SDCARD_PATCHED 0xDA #define DEVICE_ID_SDCARD_PATCHED 0xDA
@ -34,6 +32,60 @@
#define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2' #define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2'
#define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC ' #define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC '
enum NodeTypes
{
NODE_TYPE_DEV_DF = 0,
NODE_TYPE_DEV_ATFS = 1,
NODE_TYPE_DEV_ISFS = 2,
NODE_TYPE_DEV_WFS = 3,
NODE_TYPE_DEV_PCFS = 4,
NODE_TYPE_DEV_RBFS = 5,
NODE_TYPE_DEV_FAT = 6,
NODE_TYPE_DEV_FLA = 7,
NODE_TYPE_DEV_UMS = 8,
NODE_TYPE_DEV_AHCIMGR = 9,
NODE_TYPE_DEV_SHDD = 10,
NODE_TYPE_DEV_MD = 11,
NODE_TYPE_DEV_SCFM = 12,
NODE_TYPE_DEV_MMC = 13,
NODE_TYPE_DEV_TIMETRACE = 14,
NODE_TYPE_DEV_TCP_PCFS = 15
};
enum DeviceTypes
{
DEVICE_TYPE_SI = 0x01,
DEVICE_TYPE_ODD = 0x02,
DEVICE_TYPE_SLCCMPT = 0x03,
DEVICE_TYPE_SLC = 0x04,
DEVICE_TYPE_MLC = 0x05,
DEVICE_TYPE_SDCARD = 0x06,
DEVICE_TYPE_SD = 0x07,
DEVICE_TYPE_HFIO = 0x08,
DEVICE_TYPE_RAMDISK = 0x09,
DEVICE_TYPE_USB = 0x11,
DEVICE_TYPE_MLCORIG = 0x12
};
enum FsTypes
{
FS_TYPE_RAW = 0x8003,
FS_TYPE_FAT = 0x8004,
FS_TYPE_WFS = 0x8005,
FS_TYPE_ISFS = 0x8006,
FS_TYPE_ATFS = 0x8007
};
typedef struct _fs_attach_info_t
{
struct _fs_attach_info_t* next;
u16 fs_type;
u16 unkn_flags2;
u32 zeros[2];
int (*fsAttach)(void *dev_struct, int unkn_one);
u8 allowed_devices[0x0C];
} fs_attach_info_t;
typedef struct _stdio_nand_desc_t typedef struct _stdio_nand_desc_t
{ {
u32 nand_type; // nand type u32 nand_type; // nand type

View File

@ -8,6 +8,7 @@
#include "text.h" #include "text.h"
#include "hardware_registers.h" #include "hardware_registers.h"
#include "svc.h" #include "svc.h"
#include "../../common/kernel_commands.h"
// the IO buffer is put behind everything else because there is no access to this region from IOS-FS it seems // the IO buffer is put behind everything else because there is no access to this region from IOS-FS it seems
unsigned char io_buffer[0x40000] __attribute__((aligned(0x40))) __attribute__((section(".io_buffer"))); unsigned char io_buffer[0x40000] __attribute__((aligned(0x40))) __attribute__((section(".io_buffer")));
@ -206,7 +207,7 @@ static void wait_format_confirmation(void)
_printf(20, 30, "No NAND dump detected. SD Format and complete NAND dump required."); _printf(20, 30, "No NAND dump detected. SD Format and complete NAND dump required.");
_printf(20, 40, "Press the POWER button to format SD card otherwise the console will reboot in %d seconds.", timeout/10); _printf(20, 40, "Press the POWER button to format SD card otherwise the console will reboot in %d seconds.", timeout/10);
if(svcRead32(LT_GPIO_IN) & GPIO_IN_POWER_BUTTON) if(svcCustomKernelCommand(KERNEL_READ32, LT_GPIO_IN) & GPIO_IN_POWER_BUTTON)
{ {
break; break;
} }

222
ios_fs/source/fsa.c Normal file
View File

@ -0,0 +1,222 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include <stdio.h>
#include "types.h"
#include "devices.h"
#include "imports.h"
#include "fsa.h"
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! FSA redirection
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
char* FSA_AttachVolume_FillDescription_hook(char *dst, const char *src, int size)
{
char* ret = FS_STRNCPY(dst, src, size);
u8 *volDescr = (u8 *)(dst - 0x1C);
// copy in a fake volume name and enable flag that it is set
if( (FS_STRNCMP((char*)(volDescr + 0x1C), "usb", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) )
{
FS_STRNCPY((char*)(volDescr + 0xAC), "usbfat1", 8);
*volDescr |= 0x40;
}
// let's do this for SD card to, for future SD card title loading maybe
/*
if( (FS_STRNCMP((char*)(volDescr + 0x1C), "sdcard", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) )
{
FS_STRNCPY(volDescr + 0xAC, "sdfat", 7);
*volDescr |= 0x40;
}
*/
return ret;
}
int FSA_AsyncCommandCallback_hook(int result, int reply)
{
int (*FSA_ConvertErrorCode)(int result, int reply) = (void*)0x1071209C;
int res = FSA_ConvertErrorCode(result, reply);
if(reply && (*(u32*)(reply + 0x42C) != 0))
{
u32 devDescr = *(u32*)(reply + 0x42C);
int deviceType = *(u32*)(devDescr + 0x70);
if(deviceType == DEVICE_TYPE_USB) // TODO: verify it is FAT USB and not WFS USB
{
u32 command = *(u32*)(reply + 0x1C);
if(res < 0)
{
switch(command)
{
case 0x05: // FSMakeQuota -> 0x1D
case 0x1A: // FSFlushQuota -> 0x1E
case 0x1B: // FSRollbackQuota -> 0x1F
case 0x1C: // FSChangeOwner -> 0x70
case 0x1D: // FSChangeMode -> 0x20
case 0x1E: // FSRemoveQuota -> 0x72 // TODO: this actually removes the directory. we need to do something about it
case 0x20: // Unkn -> 0x74
case 0x21: // FSMakeLinkAsync -> 0x75 // TODO: this is an issue on FAT. maybe create some file which has the name of the link in it?
case 0x16: // unkn but required on install
res = 0;
break;
case 0x04:
if(res == -196642)
{
// FS_SYSLOG_OUTPUT("FSA INVALID CHARACTERS IN CREATEDIR\n");
res = 0;
}
break;
default:
break;
}
}
else
{
switch(command)
{/*
case 0x10: // FSGetStatFile
{
fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x2C));
FS_SYSLOG_OUTPUT("FSGetStatFile: %08X %08X %08X %08X\n", fsStat->flag, fsStat->owner_id, fsStat->group_id, fsStat->size);
break;
}*/
case 0x19: // FSGetInfo -> 0x18
{
switch(*(u32*)(reply + 0x228))
{
case 0x05: // FSGetStat
{
fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x22C));
if((fsStat->flag & 0xF0000000) == 0x80000000)
{
// just make every directory a quota -> probably wrong :P
fsStat->flag |= 0xE0000000;
fsStat->quota_size = 0x4000000; // max quota size
}
break;
}
default:
break;
}
break;
}
default:
break;
}
}
}
}
if(res < 0 && (*(u32*)(reply + 0x1C) != 0x19))
FS_SYSLOG_OUTPUT("FSA TEST2: res %d %08X %08X %08X\n", res, result, reply, *(u32*)(reply + 0x1C));
return res;
}
int FSA_MakeQuota_hook(u32 * devDescr, u32 *commandStruct)
{
int (*resolveNode)(u32 * devDescr) = (void*)0x1070EEDC;
int res = resolveNode(devDescr);
if(devDescr[0x70/4] == DEVICE_TYPE_USB)
{
commandStruct[0x1C/4] = 4;
}
else
{
commandStruct[0x1C/4] = 5;
}
return res;
}
/*
int FSMakeQuota(int fsa, int client, const char *path, int mode, int unkn, unsigned int size)
{
int (*callFunc)(int fsa, int client, const char *path, int mode, int unkn, unsigned int size) = (void*)0x1070BC9C;
if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0)
{
mode = 0x666;
}
int res = callFunc(fsa, client, path, mode, unkn, size);
FS_SYSLOG_OUTPUT("FSMakeQuota: res %d %08X %08X %20s %08X %08X %08X\n", res, fsa, client, path, mode, unkn, size);
return res;
}
int FSCreateDir(int fsa, int client, const char *path, int mode)
{
int (*callFunc)(int fsa, int client, const char *path, int mode) = (void*)0x1070BEBC;
if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0)
{
mode = 0x666;
}
int res = callFunc(fsa, client, path, mode);
FS_SYSLOG_OUTPUT("FSCreateDir: res %d %08X %08X %s %08X\n", res, fsa, client, path, mode);
return res;
}
int FSChangeDir(int a1, char *dir)
{
int (*callFunc)(int a1, char* a2) = (void*)0x1070EB7C;
int res = callFunc(a1, dir);
FS_SYSLOG_OUTPUT("FSChangeDir: res %d %s\n", res, dir);
return res;
}
int FSOpenFile(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6)
{
int (*callFunc)(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6) = (void*)0x1070AF08;
if(FS_STRNCMP(dir, "/vol/mcp_devmgr", 15) == 0)
{
a4 = 0x666;
}
int res = callFunc(a1, a2, dir, mode, a3, a4, a5, a6);
FS_SYSLOG_OUTPUT("FSOpenFile: res %d %s %s %08X %08X %08X\n", res, dir, mode, a4, a5, a6);
return res;
}
int FSWriteFileIssueCommand(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8)
{
int (*callFunc)(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8) = (void*)0x1070A7A4;
int res = callFunc(a1, a2, a3, a4, a5, a6, a7, a8);
FS_SYSLOG_OUTPUT("FSWriteFile: res %d %08X %08X %08X %08X %08X %08X\n", res, a3, a4, a5, a6, a7, a8);
return res;
}
*/

42
ios_fs/source/fsa.h Normal file
View File

@ -0,0 +1,42 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _FSA_H_
#define _FSA_H_
typedef struct
{
u32 flag;
u32 permission;
u32 owner_id;
u32 group_id;
u32 size; // size in bytes
u32 physblock_size; // physical size on disk in bytes
u64 quota_size;
u32 id;
u32 ctime;
u32 mtime;
u32 unk2[0x0D];
}fileStat_s;
#endif

View File

@ -5,10 +5,11 @@
.extern createDevThread_entry .extern createDevThread_entry
.globl createDevThread_hook .globl createDevThread_hook
createDevThread_hook: createDevThread_hook:
push {r0,lr} push {r0,r1,lr}
ldr r0, [r4, #0x8] ldr r0, [r4, #0x8]
mov r1, r7
bl createDevThread_entry bl createDevThread_entry
pop {r0,lr} pop {r0,r1,lr}
# restore original instruction # restore original instruction
pop {r4-r8,pc} pop {r4-r8,pc}
@ -56,6 +57,14 @@ sdcardRead_original:
bx r4 bx r4
.word 0x107BDDD4 .word 0x107BDDD4
#############################################################################################
# FSA functions
#############################################################################################
.globl FSA_MakeQuota_asm_hook
FSA_MakeQuota_asm_hook:
mov r1, r5
b FSA_MakeQuota_hook
############################################################################################# #############################################################################################
# DEBUG STUFF # DEBUG STUFF
############################################################################################# #############################################################################################

View File

@ -11,9 +11,11 @@
#define FS_SLEEP ((void (*)(int))0x1071D668) #define FS_SLEEP ((void (*)(int))0x1071D668)
#define FS_MEMCPY ((void* (*)(void*, const void*, u32))0x107F4F7C) #define FS_MEMCPY ((void* (*)(void*, const void*, u32))0x107F4F7C)
#define FS_MEMSET ((void* (*)(void*, int, u32))0x107F5018) #define FS_MEMSET ((void* (*)(void*, int, u32))0x107F5018)
#define FS_VSNPRINTF ((int (*)(char * s, size_t n, const char * format, va_list arg))0x107F5F68) #define FS_VSNPRINTF ((int (*)(char * s, u32 n, const char * format, va_list arg))0x107F5F68)
#define FS_SNPRINTF ((int (*)(char * s, size_t n, const char * format, ...))0x107F5FB4) #define FS_SNPRINTF ((int (*)(char * s, u32 n, const char * format, ...))0x107F5FB4)
#define FS_STRNCMP ((int (*)(const char *s1, const char *s2, u32 size))0x107F6138)
#define FS_STRNCPY ((char* (*)(char *s1, const char *s2, u32 size))0x107F60DC)
#define FS_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0x107F0C84)
#define FS_RAW_READ1 ((int (*)(int handle, u32 offset_high, u32 offset_low, u32 size, void* buf, void *callback, int callback_arg))0x10732BC0) #define FS_RAW_READ1 ((int (*)(int handle, u32 offset_high, u32 offset_low, u32 size, void* buf, void *callback, int callback_arg))0x10732BC0)
#define FS_SDIO_DOREADWRITECOMMAND ((int (*)(int, void*, u32, void*, void*))0x10718A8C) #define FS_SDIO_DOREADWRITECOMMAND ((int (*)(int, void*, u32, void*, void*))0x10718A8C)

View File

@ -2,28 +2,56 @@
#include "sdio.h" #include "sdio.h"
#include "dumper.h" #include "dumper.h"
#include "imports.h" #include "imports.h"
#include "devices.h"
#include "svc.h"
#include "../../common/config_types.h"
#include "../../common/kernel_commands.h"
#define INITIALIZING_FLA 0x07 void createDevThread_entry(int node_type, u32 *dev_handles)
#define INITIALIZING_MMC 0x0D
int getPhysicalDeviceHandle(u32 device);
void createDevThread_entry(int initialization_type)
{ {
if(initialization_type == INITIALIZING_MMC) FS_SYSLOG_OUTPUT("FSA: %s thread created\n", (char*)dev_handles[0]);
if(node_type == NODE_TYPE_DEV_MMC)
{ {
sdcard_init(); cfw_config_t cfw_config;
FS_MEMSET(&cfw_config, 0, sizeof(cfw_config));
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
if(cfw_config.redNAND)
{
sdcard_init();
}
} }
else if(node_type == NODE_TYPE_DEV_UMS)
//if(initialization_type == INITIALIZING_FLA)
//{
//dump_nand_complete();
//}
if(initialization_type == 0x01) // unknown but after SLC init no read/write done at this point yet
{ {
if(check_nand_dump() == 0) // instead of hooking into attach at 0x10732FBC...lets do this and let the system do the mount
fs_attach_info_t * info = (fs_attach_info_t *)(*(u32*)0x1091C2E4);
do
{
if(info->fs_type == FS_TYPE_FAT)
{
int i;
for(i = 0; i < sizeof(info->allowed_devices); i++)
{
if(info->allowed_devices[i] == 0)
{
info->allowed_devices[i] = DEVICE_TYPE_USB;
break;
}
}
break;
}
info = info->next;
}
while(info);
}
else if(node_type == NODE_TYPE_DEV_ATFS) // ATFS is started right before ISFS for slc/slccmpt
{
cfw_config_t cfw_config;
FS_MEMSET(&cfw_config, 0, sizeof(cfw_config));
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
if(cfw_config.redNAND && (check_nand_dump() == 0))
{ {
clearScreen(0x000000FF); clearScreen(0x000000FF);
_printf(20, 20, "welcome to redNAND!"); _printf(20, 20, "welcome to redNAND!");

View File

@ -24,6 +24,6 @@ int svcInvalidateDCache(void* address, u32 size);
int svcFlushDCache(void* address, u32 size); int svcFlushDCache(void* address, u32 size);
void svcShutdown(int shutdown_type); void svcShutdown(int shutdown_type);
u32 svcRead32(u32 addr); int svcCustomKernelCommand(u32 command, ...);
#endif #endif

View File

@ -61,8 +61,8 @@ svcShutdown:
.word 0xE7F072F0 .word 0xE7F072F0
bx lr bx lr
.global svcRead32 .global svcCustomKernelCommand
.type svcRead32, %function .type svcCustomKernelCommand, %function
svcRead32: svcCustomKernelCommand:
.word 0xE7F081F0 .word 0xE7F081F0
bx lr bx lr

View File

@ -24,7 +24,7 @@
#ifndef __CONFIG_H_ #ifndef __CONFIG_H_
#define __CONFIG_H_ #define __CONFIG_H_
#include "../../src/cfw_config.h" #include "../../common/config_types.h"
extern cfw_config_t cfw_config; extern cfw_config_t cfw_config;

View File

@ -26,8 +26,10 @@
#include "types.h" #include "types.h"
#define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) #define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB
#define ARM_BL(addr, func) (0xEB000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) #define ARM_BL(addr, func) (0xEB000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB
#define THUMB_B(addr, func) ((0xE000 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x7FF))) // +-2KB
#define THUMB_BL(addr, func) ((0xF000F800 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x0FFF)) | ((((u32)(func) - (u32)(addr) - 4) << 4) & 0x7FFF000)) // +-4MB
typedef struct typedef struct
{ {

View File

@ -0,0 +1,59 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "types.h"
#include "elf_patcher.h"
#include "config.h"
#include "ios_acp_patches.h"
#include "../../ios_acp/ios_acp.bin.h"
#include "../../ios_acp/ios_acp_syms.h"
#define ACP_CODE_BASE_PHYS_ADDR (-0xE0000000 + 0x12900000)
extern const patch_table_t acp_patches_table[];
extern const patch_table_t acp_patches_table_end[];
u32 acp_get_phys_code_base(void)
{
return _text_start + ACP_CODE_BASE_PHYS_ADDR;
}
void acp_run_patches(u32 ios_elf_start)
{
section_write(ios_elf_start, _text_start, (void*)acp_get_phys_code_base(), _text_end - _text_start);
// hook acp fsa raw read function
section_write_word(ios_elf_start, 0xE00601F0, ARM_BL(0xE00601F0, ACP_FSARawRead_hook));
// patch logs to output more info
section_write_word(ios_elf_start, 0xE009801C, ARM_B(0xE009801C, 0xE00C4D54));
section_write_word(ios_elf_start, 0xE00D87B0, ARM_B(0xE00D87B0, 0xE00C4D54));
section_write_word(ios_elf_start, 0xE00D6DE8, ARM_B(0xE00D6DE8, 0xE00C4D54));
section_write_word(ios_elf_start, 0xE009A0C4, 0xE3A00000);
// patch acp remove quota to always try recursive directory remove after remove quota
section_write_word(ios_elf_start, 0xE002E170, 0xEA000021);
u32 patch_count = (u32)(((u8*)acp_patches_table_end) - ((u8*)acp_patches_table)) / sizeof(patch_table_t);
patch_table_entries(ios_elf_start, acp_patches_table, patch_count);
}

View File

@ -0,0 +1,30 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _ACP_PATCHES_H_
#define _ACP_PATCHES_H_
u32 acp_get_phys_code_base(void);
void acp_run_patches(u32 ios_elf_start);
#endif

View File

@ -0,0 +1,11 @@
.arm
patch_wfs_partition_check:
mov r0, #0
.globl acp_patches_table, acp_patches_table_end
acp_patches_table:
# origin data size
.word 0xE00605D0, patch_wfs_partition_check, 4
acp_patches_table_end:

View File

@ -24,6 +24,7 @@
#include "types.h" #include "types.h"
#include "elf_patcher.h" #include "elf_patcher.h"
#include "ios_fs_patches.h" #include "ios_fs_patches.h"
#include "config.h"
#include "../../ios_fs/ios_fs_syms.h" #include "../../ios_fs/ios_fs_syms.h"
#define FS_PHYS_DIFF 0 #define FS_PHYS_DIFF 0
@ -63,22 +64,39 @@ void fs_run_patches(u32 ios_elf_start)
// patch FS logging // patch FS logging
section_write_word(ios_elf_start, FS_PRINTF_SYSLOG, ARM_B(FS_PRINTF_SYSLOG, FS_SYSLOG_OUTPUT)); section_write_word(ios_elf_start, FS_PRINTF_SYSLOG, ARM_B(FS_PRINTF_SYSLOG, FS_SYSLOG_OUTPUT));
section_write_word(ios_elf_start, CALL_FS_REGISTERMDPHYSICALDEVICE, ARM_BL(CALL_FS_REGISTERMDPHYSICALDEVICE, registerMdDevice_hook)); if(cfw_config.redNAND)
section_write_word(ios_elf_start, FS_GETMDDEVICEBYID + 8, ARM_BL((FS_GETMDDEVICEBYID + 8), getMdDeviceById_hook)); {
section_write_word(ios_elf_start, CALL_FS_REGISTERMDPHYSICALDEVICE, ARM_BL(CALL_FS_REGISTERMDPHYSICALDEVICE, registerMdDevice_hook));
section_write_word(ios_elf_start, FS_GETMDDEVICEBYID + 8, ARM_BL((FS_GETMDDEVICEBYID + 8), getMdDeviceById_hook));
section_write_word(ios_elf_start, FS_SDCARD_READ1, ARM_B(FS_SDCARD_READ1, sdcardRead_patch)); section_write_word(ios_elf_start, FS_SDCARD_READ1, ARM_B(FS_SDCARD_READ1, sdcardRead_patch));
section_write_word(ios_elf_start, FS_SDCARD_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_patch)); section_write_word(ios_elf_start, FS_SDCARD_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_patch));
section_write_word(ios_elf_start, FS_SLC_READ1, ARM_B(FS_SLC_READ1, slcRead1_patch)); section_write_word(ios_elf_start, FS_SLC_READ1, ARM_B(FS_SLC_READ1, slcRead1_patch));
section_write_word(ios_elf_start, FS_SLC_READ2, ARM_B(FS_SLC_READ2, slcRead2_patch)); section_write_word(ios_elf_start, FS_SLC_READ2, ARM_B(FS_SLC_READ2, slcRead2_patch));
section_write_word(ios_elf_start, FS_SLC_WRITE1, ARM_B(FS_SLC_WRITE1, slcWrite1_patch)); section_write_word(ios_elf_start, FS_SLC_WRITE1, ARM_B(FS_SLC_WRITE1, slcWrite1_patch));
section_write_word(ios_elf_start, FS_SLC_WRITE2, ARM_B(FS_SLC_WRITE2, slcWrite2_patch)); section_write_word(ios_elf_start, FS_SLC_WRITE2, ARM_B(FS_SLC_WRITE2, slcWrite2_patch));
//section_write_word(ios_elf_start, FS_USB_READ, ARM_B(FS_USB_READ, usbRead_patch)); //section_write_word(ios_elf_start, FS_USB_READ, ARM_B(FS_USB_READ, usbRead_patch));
//section_write_word(ios_elf_start, FS_USB_WRITE, ARM_B(FS_USB_WRITE, usbWrite_patch)); //section_write_word(ios_elf_start, FS_USB_WRITE, ARM_B(FS_USB_WRITE, usbWrite_patch));
}
section_write_word(ios_elf_start, 0x1070F87C, ARM_BL(0x1070F87C, FSA_AttachVolume_FillDescription_hook));
section_write_word(ios_elf_start, 0x10700EFC, ARM_BL(0x10700EFC, FSA_AsyncCommandCallback_hook));
// patch mounting FAT and allow all devices instead of only SD card
section_write_word(ios_elf_start, 0x1078E074, 0xEA000002);
// patch FSA_MakeQuota to not store command -> command is modified depending on wether it is USB FAT or not
section_write_word(ios_elf_start, 0x1070BE0C, 0xE1A00000);
section_write_word(ios_elf_start, 0x1070BE00, ARM_BL(0x1070BE00, FSA_MakeQuota_asm_hook));
section_write_word(ios_elf_start, FS_CREATEDEVTHREAD_HOOK, ARM_B(FS_CREATEDEVTHREAD_HOOK, createDevThread_hook)); section_write_word(ios_elf_start, FS_CREATEDEVTHREAD_HOOK, ARM_B(FS_CREATEDEVTHREAD_HOOK, createDevThread_hook));
u32 patch_count = (u32)(((u8*)fs_patches_table_end) - ((u8*)fs_patches_table)) / sizeof(patch_table_t); u32 patch_count = (u32)(((u8*)fs_patches_table_end) - ((u8*)fs_patches_table)) / sizeof(patch_table_t);
patch_table_entries(ios_elf_start, fs_patches_table, patch_count); patch_table_entries(ios_elf_start, fs_patches_table, patch_count);
//section_write_word(ios_elf_start, 0x10701F6C, ARM_BL(0x10701F6C, FSMakeQuota));
//section_write_word(ios_elf_start, 0x10702764, ARM_BL(0x10702764, FSCreateDir));
//section_write_word(ios_elf_start, 0x1070278C, ARM_BL(0x1070278C, FSChangeDir));
//section_write_word(ios_elf_start, 0x107024B4, ARM_BL(0x107024B4, FSOpenFile));
//section_write_word(ios_elf_start, 0x10703F4C, ARM_BL(0x10703F4C, FSWriteFileIssueCommand));
} }

View File

@ -52,8 +52,11 @@ void mcp_run_patches(u32 ios_elf_start)
section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24); section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24);
} }
section_write_word(ios_elf_start, (_text_start - 4), cfw_config.launchImage);
u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t); u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t);
patch_table_entries(ios_elf_start, mcp_patches_table, patch_count); patch_table_entries(ios_elf_start, mcp_patches_table, patch_count);
// patch MCP syslogs
//section_write_word(ios_elf_start, 0x05055438, ARM_B(0x05055438, 0x0503DCF8));
//section_write_word(ios_elf_start, 0x05056C2C, ARM_B(0x05056C2C, 0x0503DCF8));
//section_write_word(ios_elf_start, 0x0500A4D2, THUMB_BL(0x0500A4D2, mcpThumb2ArmLog));
} }

View File

@ -5,6 +5,11 @@
# mov r0, #0 # mov r0, #0
# mov r0, #0 # mov r0, #0
patch_wfs_partition_check:
.thumb
mov r0, #0
mov r0, #0
patch_MCP_authentication_check: patch_MCP_authentication_check:
.thumb .thumb
mov r0, #0 mov r0, #0
@ -29,6 +34,8 @@ mcp_patches_table:
.word 0x05052C44, patch_IOSC_VerifyPubkeySign, 8 .word 0x05052C44, patch_IOSC_VerifyPubkeySign, 8
.word 0x05052A90, patch_cert_verification, 8 .word 0x05052A90, patch_cert_verification, 8
.word 0x05054D6C, patch_cached_cert_check, 8 .word 0x05054D6C, patch_cached_cert_check, 8
.word 0x0502ADF6, patch_wfs_partition_check, 4
# .word 0x05014AD8, patch_wfs_partition_check, 4
# over an hour, MCP crash prevention # over an hour, MCP crash prevention
.word 0x05022474, 0xFFFFFFFF, 4 .word 0x05022474, 0xFFFFFFFF, 4
# MCP patches end here actually but lets tread the ACP patches as MCP as there are only patches # MCP patches end here actually but lets tread the ACP patches as MCP as there are only patches

View File

@ -22,8 +22,10 @@
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include "types.h" #include "types.h"
#include "../../common/kernel_commands.h"
#include "elf_patcher.h" #include "elf_patcher.h"
#include "ios_mcp_patches.h" #include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "ios_fs_patches.h" #include "ios_fs_patches.h"
#include "ios_bsp_patches.h" #include "ios_bsp_patches.h"
#include "kernel_patches.h" #include "kernel_patches.h"
@ -55,9 +57,35 @@ static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] =
0x00000001 // pid (MCP) 0x00000001 // pid (MCP)
}; };
static u32 kernel_syscall_0x81(u32 address) static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3)
{ {
return *(volatile u32*)address; switch(command)
{
case KERNEL_READ32:
{
return *(volatile u32*)arg1;
}
case KERNEL_WRITE32:
{
*(volatile u32*)arg1 = arg2;
break;
}
case KERNEL_MEMCPY:
{
//set_domain_register(0xFFFFFFFF);
kernel_memcpy((void*)arg1, (void*) arg2, arg3);
break;
}
case KERNEL_GET_CFW_CONFIG:
{
//set_domain_register(0xFFFFFFFF);
kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
break;
}
default:
return -1;
}
return 0;
} }
static int kernel_read_otp_internal(int index, void* out_buf, u32 size) static int kernel_read_otp_internal(int index, void* out_buf, u32 size)
@ -101,14 +129,11 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
//! try to keep the order of virt. addresses to reduce the memmove amount //! 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);
acp_run_patches(ios_elf_start);
if(cfw_config.redNAND) if(cfw_config.redNAND && cfw_config.seeprom_red)
{ bsp_run_patches(ios_elf_start);
fs_run_patches(ios_elf_start);
if(cfw_config.seeprom_red)
bsp_run_patches(ios_elf_start);
}
restore_mmu(control_register); restore_mmu(control_register);
enable_interrupts(level); enable_interrupts(level);
@ -120,7 +145,7 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
void kernel_run_patches(u32 ios_elf_start) void kernel_run_patches(u32 ios_elf_start)
{ {
section_write(ios_elf_start, (u32)__KERNEL_CODE_START, __KERNEL_CODE_START, __KERNEL_CODE_END - __KERNEL_CODE_START); section_write(ios_elf_start, (u32)__KERNEL_CODE_START, __KERNEL_CODE_START, __KERNEL_CODE_END - __KERNEL_CODE_START);
section_write_word(ios_elf_start, 0x0812A120, ARM_BL(0x0812A120, kernel_launch_ios)); //section_write_word(ios_elf_start, 0x0812A120, ARM_BL(0x0812A120, kernel_launch_ios));
section_write(ios_elf_start, 0x08140DE0, KERNEL_MCP_IOMAPPINGS_STRUCT, sizeof(KERNEL_MCP_IOMAPPINGS_STRUCT)); section_write(ios_elf_start, 0x08140DE0, KERNEL_MCP_IOMAPPINGS_STRUCT, sizeof(KERNEL_MCP_IOMAPPINGS_STRUCT));

View File

@ -26,6 +26,7 @@
#include "utils.h" #include "utils.h"
#include "redirection_setup.h" #include "redirection_setup.h"
#include "ios_mcp_patches.h" #include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "ios_fs_patches.h" #include "ios_fs_patches.h"
#include "ios_bsp_patches.h" #include "ios_bsp_patches.h"
#include "instant_patches.h" #include "instant_patches.h"
@ -99,17 +100,15 @@ int _main()
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size); kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
if(cfw_config.redNAND) kernel_memcpy((void*)fs_get_phys_code_base(), payloads->data, payloads->size);
{ payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
kernel_memcpy((void*)fs_get_phys_code_base(), payloads->data, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
if(cfw_config.seeprom_red) if(cfw_config.redNAND && cfw_config.seeprom_red)
{ kernel_memcpy((void*)bsp_get_phys_code_base(), payloads->data, payloads->size);
kernel_memcpy((void*)bsp_get_phys_code_base(), payloads->data, payloads->size); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
} kernel_memcpy((void*)acp_get_phys_code_base(), payloads->data, payloads->size);
} payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size); kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );

View File

@ -48,4 +48,9 @@ static inline void restore_mmu(unsigned int control_register)
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register)); asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register));
} }
static inline void set_domain_register(unsigned int domain_register)
{
asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register));
}
#endif #endif

View File

@ -10,7 +10,7 @@ SECTIONS
} }
_text_end = .; _text_end = .;
.bss 0x050BE000 : { .bss 0x050BD000 : {
_bss_start = .; _bss_start = .;
*(.bss*); *(.bss*);
} }

View File

@ -30,6 +30,8 @@
#include "text.h" #include "text.h"
#include "logger.h" #include "logger.h"
#include "fsa.h" #include "fsa.h"
#include "wupserver.h"
#include "../../common/kernel_commands.h"
#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 #define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6
#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 #define IOS_ERROR_INVALID_ARG 0xFFFFFFE3
@ -40,6 +42,7 @@
#define IOCTL_MEM_WRITE 0x00 #define IOCTL_MEM_WRITE 0x00
#define IOCTL_MEM_READ 0x01 #define IOCTL_MEM_READ 0x01
#define IOCTL_SVC 0x02 #define IOCTL_SVC 0x02
#define IOCTL_KILL_SERVER 0x03
#define IOCTL_MEMCPY 0x04 #define IOCTL_MEMCPY 0x04
#define IOCTL_REPEATED_WRITE 0x05 #define IOCTL_REPEATED_WRITE 0x05
#define IOCTL_KERN_READ32 0x06 #define IOCTL_KERN_READ32 0x06
@ -71,6 +74,7 @@
#define IOCTL_FSA_RAW_CLOSE 0x57 #define IOCTL_FSA_RAW_CLOSE 0x57
#define IOCTL_FSA_CHANGEMODE 0x58 #define IOCTL_FSA_CHANGEMODE 0x58
static int ipcNodeKilled;
static u8 threadStack[0x1000] __attribute__((aligned(0x20))); static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
static int ipc_ioctl(ipcmessage *message) static int ipc_ioctl(ipcmessage *message)
@ -123,6 +127,12 @@ static int ipc_ioctl(ipcmessage *message)
} }
break; break;
} }
case IOCTL_KILL_SERVER:
{
ipcNodeKilled = 1;
wupserver_deinit();
break;
}
case IOCTL_MEMCPY: case IOCTL_MEMCPY:
{ {
if(message->ioctl.length_in < 12) if(message->ioctl.length_in < 12)
@ -180,7 +190,7 @@ static int ipc_ioctl(ipcmessage *message)
{ {
for(u32 i = 0; i < (message->ioctl.length_io/4); i++) for(u32 i = 0; i < (message->ioctl.length_io/4); i++)
{ {
message->ioctl.buffer_io[i] = svcRead32(message->ioctl.buffer_in[0] + i * 4); message->ioctl.buffer_io[i] = svcCustomKernelCommand(KERNEL_READ32, message->ioctl.buffer_in[0] + i * 4);
} }
} }
break; break;
@ -420,61 +430,76 @@ static int ipc_thread(void *arg)
int queueId = svcCreateMessageQueue(messageQueue, sizeof(messageQueue) / 4); int queueId = svcCreateMessageQueue(messageQueue, sizeof(messageQueue) / 4);
if(svcRegisterResourceManager("/dev/iosuhax", queueId) != 0) if(svcRegisterResourceManager("/dev/iosuhax", queueId) == 0)
{ {
return 0; while(!ipcNodeKilled)
{
res = svcReceiveMessage(queueId, &message, 0);
if(res < 0)
{
usleep(10000);
continue;
}
switch(message->command)
{
case IOS_OPEN:
{
log_printf("IOS_OPEN\n");
res = 0;
break;
}
case IOS_CLOSE:
{
log_printf("IOS_CLOSE\n");
res = 0;
break;
}
case IOS_IOCTL:
{
log_printf("IOS_IOCTL\n");
res = ipc_ioctl(message);
break;
}
case IOS_IOCTLV:
{
log_printf("IOS_IOCTLV\n");
res = 0;
break;
}
default:
{
log_printf("unexpected command 0x%X\n", message->command);
res = IOS_ERROR_UNKNOWN_VALUE;
break;
}
}
svcResourceReply(message, res);
}
} }
while(1) svcDestroyMessageQueue(queueId);
{ return 0;
res = svcReceiveMessage(queueId, &message, 0);
if(res < 0)
{
usleep(10000);
continue;
}
switch(message->command)
{
case IOS_OPEN:
{
log_printf("IOS_OPEN\n");
res = 0;
break;
}
case IOS_CLOSE:
{
log_printf("IOS_CLOSE\n");
res = 0;
break;
}
case IOS_IOCTL:
{
log_printf("IOS_IOCTL\n");
res = ipc_ioctl(message);
break;
}
case IOS_IOCTLV:
{
log_printf("IOS_IOCTLV\n");
res = 0;
break;
}
default:
{
log_printf("unexpected command 0x%X\n", message->command);
res = IOS_ERROR_UNKNOWN_VALUE;
break;
}
}
svcResourceReply(message, res);
}
} }
void ipc_init(void) void ipc_init(void)
{ {
ipcNodeKilled = 0;
int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1); int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if(threadId >= 0) if(threadId >= 0)
svcStartThread(threadId); svcStartThread(threadId);
} }
void ipc_deinit(void)
{
int fd = svcOpen("/dev/iosuhax", 0);
if(fd >= 0)
{
int dummy = 0;
svcIoctl(fd, IOCTL_KILL_SERVER, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
svcClose(fd);
}
}

View File

@ -2,5 +2,6 @@
#define _IPC_H_ #define _IPC_H_
void ipc_init(); void ipc_init();
void ipc_deinit();
#endif #endif

View File

@ -1,247 +1,30 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "imports.h" #include "wupserver.h"
#include "net_ifmgr_ncl.h" #include "ipc.h"
#include "socket.h"
#include "fsa.h"
#include "svc.h" #include "svc.h"
#include "text.h" #include "text.h"
#include "logger.h" #include "../../common/config_types.h"
#include "ipc.h" #include "../../common/kernel_commands.h"
static bool serverKilled;
static int threadsStarted = 0; static int threadsStarted = 0;
// overwrites command_buffer with response
// returns length of response (or 0 for no response, negative for error)
int serverCommandHandler(u32* command_buffer, u32 length)
{
if(!command_buffer || !length) return -1;
int out_length = 4;
switch(command_buffer[0])
{
case 0:
// write
// [cmd_id][addr]
{
void* dst = (void*)command_buffer[1];
memcpy(dst, &command_buffer[2], length - 8);
}
break;
case 1:
// read
// [cmd_id][addr][length]
{
void* src = (void*)command_buffer[1];
length = command_buffer[2];
memcpy(&command_buffer[1], src, length);
out_length = length + 4;
}
break;
case 2:
// svc
// [cmd_id][svc_id]
{
int svc_id = command_buffer[1];
int size_arguments = length - 8;
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
// return error code as data
out_length = 8;
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
}
break;
case 3:
// kill
// [cmd_id]
{
serverKilled = true;
}
break;
case 4:
// memcpy
// [dst][src][size]
{
void* dst = (void*)command_buffer[1];
void* src = (void*)command_buffer[2];
int size = command_buffer[3];
memcpy(dst, src, size);
}
break;
case 5:
// repeated-write
// [address][value][n]
{
u32* dst = (u32*)command_buffer[1];
u32* cache_range = (u32*)(command_buffer[1] & ~0xFF);
u32 value = command_buffer[2];
u32 n = command_buffer[3];
u32 old = *dst;
int i;
for(i = 0; i < n; i++)
{
if(*dst != old)
{
if(*dst == 0x0) old = *dst;
else
{
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
}
}else
{
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}
}
break;
default:
// unknown command
return -2;
break;
}
// no error !
command_buffer[0] = 0x00000000;
return out_length;
}
void serverClientHandler(int sock)
{
u32 command_buffer[0x180];
while(!serverKilled)
{
int ret = recv(sock, command_buffer, sizeof(command_buffer), 0);
if(ret <= 0) break;
ret = serverCommandHandler(command_buffer, ret);
if(ret > 0)
{
send(sock, command_buffer, ret, 0);
}else if(ret < 0)
{
send(sock, &ret, sizeof(int), 0);
}
}
closesocket(sock);
}
void serverListenClients()
{
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in server;
memset(&server, 0x00, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = 1337;
server.sin_addr.s_addr = 0;
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
closesocket(sock);
return;
}
if(listen(sock, 1) < 0)
{
closesocket(sock);
return;
}
while(!serverKilled)
{
int csock = accept(sock, NULL, NULL);
if(csock < 0)
break;
serverClientHandler(csock);
}
closesocket(sock);
}
int _main(void *arg)
{
while(ifmgrnclInit() <= 0)
{
//print(0, 0, "opening /dev/net/ifmgr/ncl...");
usleep(1000);
}
while(true)
{
u16 out0, out1;
int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0);
if(!ret0 && out0 == 1) break;
int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1);
if(!ret1 && out1 == 1) break;
//print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1);
usleep(1000);
}
while(socketInit() <= 0)
{
//print(0, 0, "opening /dev/socket...");
usleep(1000);
}
log_init(0xC0A8B203);
//print(0, 0, "opened /dev/socket !");
usleep(5*1000*1000);
//print(0, 10, "attempting sockets !");
serverKilled = false;
while(1)
{
if(!serverKilled)
{
serverListenClients();
}
usleep(1000*1000);
}
return 0;
}
int _startMainThread(void) int _startMainThread(void)
{ {
if(threadsStarted == 0) if(threadsStarted == 0)
{ {
threadsStarted = 1; threadsStarted = 1;
cfw_config_t cfw_config;
memset(&cfw_config, 0, sizeof(cfw_config));
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
int * launchImageConfigured = (int *)(0x05116000 - 4); if(cfw_config.launchImage)
if(*launchImageConfigured != 0)
{ {
drawSplashScreen(); drawSplashScreen();
} }
int threadId = svcCreateThread(_main, 0, (u32*)(0x050BD000 + 0x1000), 0x1000, 0x78, 1); wupserver_init();
if(threadId >= 0)
svcStartThread(threadId);
ipc_init(); ipc_init();
} }
return 0; return 0;

View File

@ -153,6 +153,20 @@ int listen(int sockfd, int backlog)
return ret; return ret;
} }
int shutdown(int sockfd, int how)
{
u8* iobuf = allocIobuf(0x8);
u32* inbuf = (u32*)iobuf;
inbuf[0] = sockfd;
inbuf[1] = how;
int ret = svcIoctl(socket_handle, 0x10, inbuf, 0x8, NULL, 0);
freeIobuf(iobuf);
return ret;
}
int recv(int sockfd, void *buf, size_t len, int flags) int recv(int sockfd, void *buf, size_t len, int flags)
{ {
if(!len) return -101; if(!len) return -101;

View File

@ -23,9 +23,10 @@ int svcFlushDCache(void* address, u32 size);
int svcCreateThread(int (*callback)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, int detached); int svcCreateThread(int (*callback)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, int detached);
int svcStartThread(int threadId); int svcStartThread(int threadId);
int svcCreateMessageQueue(u32 *ptr, u32 n_msgs); int svcCreateMessageQueue(u32 *ptr, u32 n_msgs);
int svcDestroyMessageQueue(int queueid);
int svcRegisterResourceManager(const char* device, int queueid); int svcRegisterResourceManager(const char* device, int queueid);
int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags); int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags);
int svcResourceReply(ipcmessage * ipc_message, u32 result); int svcResourceReply(ipcmessage * ipc_message, u32 result);
u32 svcRead32(u32 addr); int svcCustomKernelCommand(u32 command, ...);
#endif #endif

View File

@ -20,6 +20,12 @@ svcCreateMessageQueue:
.word 0xE7F00CF0 .word 0xE7F00CF0
bx lr bx lr
.global svcDestroyMessageQueue
.type svcDestroyMessageQueue, %function
svcDestroyMessageQueue:
.word 0xE7F00DF0
bx lr
.global svcReceiveMessage .global svcReceiveMessage
.type svcReceiveMessage, %function .type svcReceiveMessage, %function
svcReceiveMessage: svcReceiveMessage:
@ -92,8 +98,8 @@ svcFlushDCache:
.word 0xE7F052F0 .word 0xE7F052F0
bx lr bx lr
.global svcRead32 .global svcCustomKernelCommand
.type svcRead32, %function .type svcCustomKernelCommand, %function
svcRead32: svcCustomKernelCommand:
.word 0xE7F081F0 .word 0xE7F081F0
bx lr bx lr

250
ios_mcp/source/wupserver.c Normal file
View File

@ -0,0 +1,250 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "imports.h"
#include "net_ifmgr_ncl.h"
#include "socket.h"
#include "fsa.h"
#include "svc.h"
#include "text.h"
#include "logger.h"
#include "ipc.h"
static int serverKilled;
static int serverSocket;
static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
// overwrites command_buffer with response
// returns length of response (or 0 for no response, negative for error)
static int serverCommandHandler(u32* command_buffer, u32 length)
{
if(!command_buffer || !length) return -1;
int out_length = 4;
switch(command_buffer[0])
{
case 0:
// write
// [cmd_id][addr]
{
void* dst = (void*)command_buffer[1];
memcpy(dst, &command_buffer[2], length - 8);
}
break;
case 1:
// read
// [cmd_id][addr][length]
{
void* src = (void*)command_buffer[1];
length = command_buffer[2];
memcpy(&command_buffer[1], src, length);
out_length = length + 4;
}
break;
case 2:
// svc
// [cmd_id][svc_id]
{
int svc_id = command_buffer[1];
int size_arguments = length - 8;
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
// return error code as data
out_length = 8;
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
}
break;
case 3:
// kill
// [cmd_id]
{
serverKilled = 1;
ipc_deinit();
}
break;
case 4:
// memcpy
// [dst][src][size]
{
void* dst = (void*)command_buffer[1];
void* src = (void*)command_buffer[2];
int size = command_buffer[3];
memcpy(dst, src, size);
}
break;
case 5:
// repeated-write
// [address][value][n]
{
u32* dst = (u32*)command_buffer[1];
u32* cache_range = (u32*)(command_buffer[1] & ~0xFF);
u32 value = command_buffer[2];
u32 n = command_buffer[3];
u32 old = *dst;
int i;
for(i = 0; i < n; i++)
{
if(*dst != old)
{
if(*dst == 0x0) old = *dst;
else
{
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
}
}else
{
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}
}
break;
default:
// unknown command
return -2;
break;
}
// no error !
command_buffer[0] = 0x00000000;
return out_length;
}
static void serverClientHandler(int sock)
{
u32 command_buffer[0x180];
while(!serverKilled)
{
int ret = recv(sock, command_buffer, sizeof(command_buffer), 0);
if(ret <= 0) break;
ret = serverCommandHandler(command_buffer, ret);
if(ret > 0)
{
send(sock, command_buffer, ret, 0);
}else if(ret < 0)
{
send(sock, &ret, sizeof(int), 0);
}
}
closesocket(sock);
}
static void serverListenClients()
{
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in server;
memset(&server, 0x00, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = 1337;
server.sin_addr.s_addr = 0;
if(bind(serverSocket, (struct sockaddr *)&server, sizeof(server)) < 0)
{
closesocket(serverSocket);
return;
}
if(listen(serverSocket, 1) < 0)
{
closesocket(serverSocket);
return;
}
while(!serverKilled)
{
int csock = accept(serverSocket, NULL, NULL);
if(csock < 0)
break;
serverClientHandler(csock);
}
closesocket(serverSocket);
serverSocket = -1;
}
static int wupserver_thread(void *arg)
{
while(ifmgrnclInit() <= 0)
{
//print(0, 0, "opening /dev/net/ifmgr/ncl...");
usleep(1000);
}
while(true)
{
u16 out0, out1;
int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0);
if(!ret0 && out0 == 1) break;
int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1);
if(!ret1 && out1 == 1) break;
//print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1);
usleep(1000);
}
while(socketInit() <= 0)
{
//print(0, 0, "opening /dev/socket...");
usleep(1000);
}
log_init(0xC0A8B203);
//print(0, 0, "opened /dev/socket !");
usleep(5*1000*1000);
//print(0, 10, "attempting sockets !");
while(1)
{
if(!serverKilled)
{
serverListenClients();
}
else
{
break;
}
usleep(1000*1000);
}
log_deinit();
return 0;
}
void wupserver_init(void)
{
serverSocket = -1;
serverKilled = 0;
int threadId = svcCreateThread(wupserver_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if(threadId >= 0)
svcStartThread(threadId);
}
void wupserver_deinit(void)
{
serverKilled = 1;
shutdown(serverSocket, SHUT_RDWR);
}

View File

@ -0,0 +1,7 @@
#ifndef WUPSERVER_H
#define WUPSERVER_H
void wupserver_init(void);
void wupserver_deinit(void);
#endif

View File

@ -325,7 +325,7 @@ class wupclient:
# print(data[:data.index(0)].decode("ascii")) # print(data[:data.index(0)].decode("ascii"))
# break # break
# else: # else:
print(data.decode("ascii")) print(data)
# file management # file management
def get_fsa_handle(self): def get_fsa_handle(self):

View File

@ -28,18 +28,7 @@
#define APP_PATH "sd:/wiiu/apps/mocha" #define APP_PATH "sd:/wiiu/apps/mocha"
#define CONFIG_PATH (APP_PATH "/config.ini") #define CONFIG_PATH (APP_PATH "/config.ini")
typedef struct #include "../common/config_types.h"
{
int viewMode;
int directLaunch;
int launchImage;
int noIosReload;
int launchSysMenu;
int redNAND;
int seeprom_red;
int otp_red;
int syshaxXml;
} cfw_config_t;
void default_config(cfw_config_t * config); void default_config(cfw_config_t * config);
int read_config(cfw_config_t * config); int read_config(cfw_config_t * config);

View File

@ -96,7 +96,9 @@ int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
//! sign is optional input //! sign is optional input
if(size) if(size)
{
*size = filesize; *size = filesize;
}
return filesize; return filesize;
} }

View File

@ -1,7 +1,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "dynamic_libs/os_functions.h" #include "dynamic_libs/os_functions.h"
#include "cfw_config.h" #include "ios_exploit.h"
#define ALIGN4(x) (((x) + 3) & ~3) #define ALIGN4(x) (((x) + 3) & ~3)
@ -36,6 +36,7 @@ typedef struct
#include "../ios_fs/ios_fs.bin.h" #include "../ios_fs/ios_fs.bin.h"
#include "../ios_bsp/ios_bsp.bin.h" #include "../ios_bsp/ios_bsp.bin.h"
#include "../ios_mcp/ios_mcp.bin.h" #include "../ios_mcp/ios_mcp.bin.h"
#include "../ios_acp/ios_acp.bin.h"
/* ROP CHAIN STARTS HERE (0x1015BD78) */ /* ROP CHAIN STARTS HERE (0x1015BD78) */
@ -324,19 +325,17 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
memcpy(payloads->data, ios_usb_bin, payloads->size); memcpy(payloads->data, ios_usb_bin, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
if(config->redNAND) payloads->size = sizeof(ios_fs_bin);
{ memcpy(payloads->data, ios_fs_bin, payloads->size);
payloads->size = sizeof(ios_fs_bin); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
memcpy(payloads->data, ios_fs_bin, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
if(config->seeprom_red) payloads->size = sizeof(ios_bsp_bin);
{ memcpy(payloads->data, ios_bsp_bin, payloads->size);
payloads->size = sizeof(ios_bsp_bin); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
memcpy(payloads->data, ios_bsp_bin, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); payloads->size = sizeof(ios_acp_bin);
} memcpy(payloads->data, ios_acp_bin, payloads->size);
} payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
payloads->size = sizeof(ios_mcp_bin); payloads->size = sizeof(ios_mcp_bin);
memcpy(payloads->data, ios_mcp_bin, payloads->size); memcpy(payloads->data, ios_mcp_bin, payloads->size);
@ -361,7 +360,6 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
} }
} }
pretend_root_hub[33] = 0x500000; pretend_root_hub[33] = 0x500000;
pretend_root_hub[78] = 0; pretend_root_hub[78] = 0;
@ -385,28 +383,30 @@ static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val)
int ExecuteIOSExploit(cfw_config_t * config) int ExecuteIOSExploit(cfw_config_t * config)
{ {
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
if(iosuhaxFd < 0) if(iosuhaxFd >= 0)
{ {
//! execute exploit int dummy = 0;
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
if(dev_uhs_0_handle < 0)
return dev_uhs_0_handle;
uhs_exploit_init(dev_uhs_0_handle, config); IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);
uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC}
IOS_Close(dev_uhs_0_handle);
}
else
{
//! do not run patches again as that will most likely crash //! do not run patches again as that will most likely crash
//! because the wupserver and the iosuhax dev node are still running //! because the wupserver and the iosuhax dev node are still running
//! just relaunch IOS with new configuration //! just relaunch IOS with new configuration
IOS_Close(iosuhaxFd); IOS_Close(iosuhaxFd);
} }
//! execute exploit
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
if(dev_uhs_0_handle < 0)
return dev_uhs_0_handle;
uhs_exploit_init(dev_uhs_0_handle, config);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);
uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC}
IOS_Close(dev_uhs_0_handle);
return 0; return 0;
} }

View File

@ -34,7 +34,7 @@
#include "dynamic_libs/sys_functions.h" #include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/vpad_functions.h" #include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/socket_functions.h" #include "dynamic_libs/socket_functions.h"
#include "cfw_config.h" #include "menu.h"
#define MAX_CONFIG_SETTINGS_EXPERT 9 #define MAX_CONFIG_SETTINGS_EXPERT 9
#define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3) #define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)