mirror of
https://github.com/wiiu-env/MochaLite.git
synced 2024-06-13 12:38:43 +02:00
Merge remote-tracking branch 'refs/remotes/dimok789/master' into sd_access
This commit is contained in:
commit
70127d64e6
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -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
|
||||
|
|
6
Makefile
6
Makefile
|
@ -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
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
|
Binary file not shown.
Before Width: | Height: | Size: 882 KiB After Width: | Height: | Size: 1.3 MiB |
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_
|
||||
#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
|
||||
|
|
|
@ -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
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
|
||||
.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
|
||||
#############################################################################################
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
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 "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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,7 +10,7 @@ SECTIONS
|
|||
}
|
||||
_text_end = .;
|
||||
|
||||
.bss 0x050BE000 : {
|
||||
.bss 0x050BD000 : {
|
||||
_bss_start = .;
|
||||
*(.bss*);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
#define _IPC_H_
|
||||
|
||||
void ipc_init();
|
||||
void ipc_deinit();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
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"))
|
||||
# break
|
||||
# else:
|
||||
print(data.decode("ascii"))
|
||||
print(data)
|
||||
|
||||
# file management
|
||||
def get_fsa_handle(self):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -96,7 +96,9 @@ int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
|
|||
|
||||
//! sign is optional input
|
||||
if(size)
|
||||
{
|
||||
*size = filesize;
|
||||
}
|
||||
|
||||
return filesize;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user