mirror of
https://github.com/wiiu-env/MochaLite.git
synced 2024-11-01 02:25:10 +01:00
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:
parent
fe9c3f8434
commit
43f1af08a3
7
.gitignore
vendored
7
.gitignore
vendored
@ -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
|
||||||
|
6
Makefile
6
Makefile
@ -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
40
common/config_types.h
Normal 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
32
common/kernel_commands.h
Normal 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
80
ios_acp/Makefile
Normal 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
23
ios_acp/link.ld
Normal 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
7
ios_acp/source/imports.h
Normal 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
41
ios_acp/source/main.c
Normal 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
29
ios_acp/source/types.h
Normal 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
|
@ -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
|
||||||
|
@ -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
222
ios_fs/source/fsa.c
Normal 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
42
ios_fs/source/fsa.h
Normal 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
|
@ -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
|
||||||
#############################################################################################
|
#############################################################################################
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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!");
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
59
ios_kernel/source/ios_acp_patches.c
Normal file
59
ios_kernel/source/ios_acp_patches.c
Normal 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);
|
||||||
|
}
|
30
ios_kernel/source/ios_acp_patches.h
Normal file
30
ios_kernel/source/ios_acp_patches.h
Normal 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
|
11
ios_kernel/source/ios_acp_patches_asm.s
Normal file
11
ios_kernel/source/ios_acp_patches_asm.s
Normal 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:
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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) );
|
||||||
|
@ -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
|
||||||
|
@ -10,7 +10,7 @@ SECTIONS
|
|||||||
}
|
}
|
||||||
_text_end = .;
|
_text_end = .;
|
||||||
|
|
||||||
.bss 0x050BE000 : {
|
.bss 0x050BD000 : {
|
||||||
_bss_start = .;
|
_bss_start = .;
|
||||||
*(.bss*);
|
*(.bss*);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
#define _IPC_H_
|
#define _IPC_H_
|
||||||
|
|
||||||
void ipc_init();
|
void ipc_init();
|
||||||
|
void ipc_deinit();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
250
ios_mcp/source/wupserver.c
Normal 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);
|
||||||
|
}
|
7
ios_mcp/source/wupserver.h
Normal file
7
ios_mcp/source/wupserver.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef WUPSERVER_H
|
||||||
|
#define WUPSERVER_H
|
||||||
|
|
||||||
|
void wupserver_init(void);
|
||||||
|
void wupserver_deinit(void);
|
||||||
|
|
||||||
|
#endif
|
@ -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):
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user