Merge remote-tracking branch 'refs/remotes/dimok789/master' into sd_access

This commit is contained in:
Maschell 2017-05-13 09:26:26 +02:00
commit 70127d64e6
44 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/*.elf
/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 $@
@$(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
$(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:
@$(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:
@ -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_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_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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

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_
#define DEVICES_H_
#define DEVICE_TYPE_SDCARD 0x06
#define DEVICE_ID_SDCARD_REAL 0x43
#define DEVICE_ID_SDCARD_PATCHED 0xDA
@ -34,6 +32,60 @@
#define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2'
#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
{
u32 nand_type; // nand type

View File

@ -8,6 +8,7 @@
#include "text.h"
#include "hardware_registers.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
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, 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;
}

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

View File

@ -11,9 +11,11 @@
#define FS_SLEEP ((void (*)(int))0x1071D668)
#define FS_MEMCPY ((void* (*)(void*, const void*, u32))0x107F4F7C)
#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_SNPRINTF ((int (*)(char * s, size_t n, const char * format, ...))0x107F5FB4)
#define FS_VSNPRINTF ((int (*)(char * s, u32 n, const char * format, va_list arg))0x107F5F68)
#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_SDIO_DOREADWRITECOMMAND ((int (*)(int, void*, u32, void*, void*))0x10718A8C)

View File

@ -2,28 +2,56 @@
#include "sdio.h"
#include "dumper.h"
#include "imports.h"
#include "devices.h"
#include "svc.h"
#include "../../common/config_types.h"
#include "../../common/kernel_commands.h"
#define INITIALIZING_FLA 0x07
#define INITIALIZING_MMC 0x0D
int getPhysicalDeviceHandle(u32 device);
void createDevThread_entry(int initialization_type)
void createDevThread_entry(int node_type, u32 *dev_handles)
{
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();
}
}
//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
else if(node_type == NODE_TYPE_DEV_UMS)
{
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);
_printf(20, 20, "welcome to redNAND!");

View File

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

View File

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

View File

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

View File

@ -26,8 +26,10 @@
#include "types.h"
#define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF))
#define ARM_BL(addr, func) (0xEB000000 | ((((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)) // +-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
{

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 "elf_patcher.h"
#include "ios_fs_patches.h"
#include "config.h"
#include "../../ios_fs/ios_fs_syms.h"
#define FS_PHYS_DIFF 0
@ -63,22 +64,39 @@ void fs_run_patches(u32 ios_elf_start)
// 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, 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));
if(cfw_config.redNAND)
{
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_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_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_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_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_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_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_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_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, 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));
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);
//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_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);
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
patch_wfs_partition_check:
.thumb
mov r0, #0
mov r0, #0
patch_MCP_authentication_check:
.thumb
mov r0, #0
@ -29,6 +34,8 @@ mcp_patches_table:
.word 0x05052C44, patch_IOSC_VerifyPubkeySign, 8
.word 0x05052A90, patch_cert_verification, 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
.word 0x05022474, 0xFFFFFFFF, 4
# 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.
***************************************************************************/
#include "types.h"
#include "../../common/kernel_commands.h"
#include "elf_patcher.h"
#include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "ios_fs_patches.h"
#include "ios_bsp_patches.h"
#include "kernel_patches.h"
@ -55,9 +57,35 @@ static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] =
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)
@ -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
mcp_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)
{
fs_run_patches(ios_elf_start);
if(cfw_config.seeprom_red)
bsp_run_patches(ios_elf_start);
}
if(cfw_config.redNAND && cfw_config.seeprom_red)
bsp_run_patches(ios_elf_start);
restore_mmu(control_register);
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)
{
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));

View File

@ -26,6 +26,7 @@
#include "utils.h"
#include "redirection_setup.h"
#include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "ios_fs_patches.h"
#include "ios_bsp_patches.h"
#include "instant_patches.h"
@ -99,17 +100,15 @@ int _main()
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, 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)
{
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) );
}
}
if(cfw_config.redNAND && cfw_config.seeprom_red)
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) );
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);
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));
}
static inline void set_domain_register(unsigned int domain_register)
{
asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register));
}
#endif

View File

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

View File

@ -30,6 +30,8 @@
#include "text.h"
#include "logger.h"
#include "fsa.h"
#include "wupserver.h"
#include "../../common/kernel_commands.h"
#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6
#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3
@ -40,6 +42,7 @@
#define IOCTL_MEM_WRITE 0x00
#define IOCTL_MEM_READ 0x01
#define IOCTL_SVC 0x02
#define IOCTL_KILL_SERVER 0x03
#define IOCTL_MEMCPY 0x04
#define IOCTL_REPEATED_WRITE 0x05
#define IOCTL_KERN_READ32 0x06
@ -71,6 +74,7 @@
#define IOCTL_FSA_RAW_CLOSE 0x57
#define IOCTL_FSA_CHANGEMODE 0x58
static int ipcNodeKilled;
static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
static int ipc_ioctl(ipcmessage *message)
@ -123,6 +127,12 @@ static int ipc_ioctl(ipcmessage *message)
}
break;
}
case IOCTL_KILL_SERVER:
{
ipcNodeKilled = 1;
wupserver_deinit();
break;
}
case IOCTL_MEMCPY:
{
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++)
{
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;
@ -420,61 +430,76 @@ static int ipc_thread(void *arg)
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)
{
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);
}
svcDestroyMessageQueue(queueId);
return 0;
}
void ipc_init(void)
{
ipcNodeKilled = 0;
int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if(threadId >= 0)
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_
void ipc_init();
void ipc_deinit();
#endif

View File

@ -1,247 +1,30 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "imports.h"
#include "net_ifmgr_ncl.h"
#include "socket.h"
#include "fsa.h"
#include "wupserver.h"
#include "ipc.h"
#include "svc.h"
#include "text.h"
#include "logger.h"
#include "ipc.h"
#include "../../common/config_types.h"
#include "../../common/kernel_commands.h"
static bool serverKilled;
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)
{
if(threadsStarted == 0)
{
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(*launchImageConfigured != 0)
if(cfw_config.launchImage)
{
drawSplashScreen();
}
int threadId = svcCreateThread(_main, 0, (u32*)(0x050BD000 + 0x1000), 0x1000, 0x78, 1);
if(threadId >= 0)
svcStartThread(threadId);
wupserver_init();
ipc_init();
}
return 0;

View File

@ -153,6 +153,20 @@ int listen(int sockfd, int backlog)
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)
{
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 svcStartThread(int threadId);
int svcCreateMessageQueue(u32 *ptr, u32 n_msgs);
int svcDestroyMessageQueue(int queueid);
int svcRegisterResourceManager(const char* device, int queueid);
int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags);
int svcResourceReply(ipcmessage * ipc_message, u32 result);
u32 svcRead32(u32 addr);
int svcCustomKernelCommand(u32 command, ...);
#endif

View File

@ -20,6 +20,12 @@ svcCreateMessageQueue:
.word 0xE7F00CF0
bx lr
.global svcDestroyMessageQueue
.type svcDestroyMessageQueue, %function
svcDestroyMessageQueue:
.word 0xE7F00DF0
bx lr
.global svcReceiveMessage
.type svcReceiveMessage, %function
svcReceiveMessage:
@ -92,8 +98,8 @@ svcFlushDCache:
.word 0xE7F052F0
bx lr
.global svcRead32
.type svcRead32, %function
svcRead32:
.global svcCustomKernelCommand
.type svcCustomKernelCommand, %function
svcCustomKernelCommand:
.word 0xE7F081F0
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"))
# break
# else:
print(data.decode("ascii"))
print(data)
# file management
def get_fsa_handle(self):

View File

@ -28,18 +28,7 @@
#define APP_PATH "sd:/wiiu/apps/mocha"
#define CONFIG_PATH (APP_PATH "/config.ini")
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;
#include "../common/config_types.h"
void default_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
if(size)
{
*size = filesize;
}
return filesize;
}

View File

@ -1,7 +1,7 @@
#include <string.h>
#include <stdio.h>
#include "dynamic_libs/os_functions.h"
#include "cfw_config.h"
#include "ios_exploit.h"
#define ALIGN4(x) (((x) + 3) & ~3)
@ -36,6 +36,7 @@ typedef struct
#include "../ios_fs/ios_fs.bin.h"
#include "../ios_bsp/ios_bsp.bin.h"
#include "../ios_mcp/ios_mcp.bin.h"
#include "../ios_acp/ios_acp.bin.h"
/* 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);
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 = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
payloads->size = sizeof(ios_fs_bin);
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 = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
}
}
payloads->size = sizeof(ios_bsp_bin);
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);
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) );
}
}
pretend_root_hub[33] = 0x500000;
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 iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
if(iosuhaxFd < 0)
if(iosuhaxFd >= 0)
{
//! execute exploit
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
if(dev_uhs_0_handle < 0)
return dev_uhs_0_handle;
int dummy = 0;
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);
IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
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
//! because the wupserver and the iosuhax dev node are still running
//! just relaunch IOS with new configuration
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;
}

View File

@ -34,7 +34,7 @@
#include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/vpad_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_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)