Simplify mocha do only disable sigchecks, add wupserver, sd overall patches and a improved .rpx redirection.

This commit is contained in:
orboditilt 2019-08-15 10:29:36 +02:00
parent aaae73531d
commit 5b57caecee
91 changed files with 611 additions and 6248 deletions

2
.gitignore vendored
View File

@ -1,4 +1,5 @@
/*.elf /*.elf
/*.cbp
/build /build
/ios_bsp/build /ios_bsp/build
/ios_bsp/ios_bsp.bin.h /ios_bsp/ios_bsp.bin.h
@ -30,3 +31,4 @@
/ios_acp/ios_acp.bin.h /ios_acp/ios_acp.bin.h
/ios_acp/*.elf /ios_acp/*.elf
/ios_acp/ios_acp_syms.h /ios_acp/ios_acp_syms.h
*.rpx

View File

@ -10,10 +10,10 @@ ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO") $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
endif endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
PREFIX := powerpc-eabi- PREFIX := powerpc-eabi-
export AS := $(PREFIX)as export AS := $(PREFIX)as
@ -28,14 +28,11 @@ export OBJCOPY := $(PREFIX)objcopy
# SOURCES is a list of directories containing source code # SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files # INCLUDES is a list of directories containing extra header files
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
TARGET := mocha TARGET := payload
BUILD := build BUILD := build
BUILD_DBG := $(TARGET)_dbg BUILD_DBG := $(TARGET)_dbg
SOURCES := src \ SOURCES := src
src/dynamic_libs \
src/fs \
src/system \
src/utils
DATA := data DATA := data
INCLUDES := src INCLUDES := src
@ -43,12 +40,12 @@ INCLUDES := src
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ CFLAGS := -std=gnu11 -mcpu=750 -meabi -mhard-float -ffast-math \
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ CXXFLAGS := -std=gnu++11 -mcpu=750 -meabi -mhard-float -ffast-math \
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
ASFLAGS := -mregnames ASFLAGS := -mregnames
LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections LDFLAGS := -nostartfiles -Wl,--gc-sections
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
Q := @ Q := @
@ -56,7 +53,7 @@ MAKEFLAGS += --no-print-directory
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -ldynamiclibs LIBS :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
@ -64,7 +61,7 @@ LIBS := -ldynamiclibs
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) \ LIBDIRS := $(CURDIR) \
$(DEVKITPPC)/lib \ $(DEVKITPPC)/lib \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 $(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -123,34 +120,22 @@ $(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_acp/ios_acp.bin.h $(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.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:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile @$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile
$(CURDIR)/ios_fs/ios_fs.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile
$(CURDIR)/ios_bsp/ios_bsp.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile
$(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:
@echo clean ... @echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile clean @$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/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_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
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -1,40 +0,0 @@
/***************************************************************************
* 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -1,80 +0,0 @@
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)

View File

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

View File

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

View File

@ -1,41 +0,0 @@
/***************************************************************************
* 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;
}

View File

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

View File

@ -1,80 +0,0 @@
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)

View File

@ -1,27 +0,0 @@
OUTPUT_ARCH(arm)
SECTIONS
{
.text 0xE6010A80 : {
_text_start = .;
*(.text*);
*(.rodata*);
}
_text_end = .;
.bss 0xE60481F0 : {
_bss_start = .;
*(.bss*);
*(COMMON);
}
.seeprom_buffer : {
_seeprom_buffer_start = .;
*(.seeprom_buffer*);
}
_bss_end = .;
/DISCARD/ : {
*(*);
}
}

View File

@ -1,81 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include "svc.h"
#include "fsa.h"
#define BSP_memcpy ((void *(*)(void*, void*, unsigned int))0xE600EA18)
#define BSP_memset ((void *(*)(void*, int, unsigned int))0xE600EAB4)
#define BSP_strncpy ((char *(*)(char*, const char*, unsigned int))0xE600F4AC)
static void* allocIobuf()
{
void* ptr = svcAlloc(0xCAFF, 0x828);
BSP_memset(ptr, 0x00, 0x828);
return ptr;
}
static void freeIobuf(void* ptr)
{
svcFree(0xCAFF, ptr);
}
int FSA_RawOpen(int fd, const char* device_path, int* outHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
BSP_strncpy((char*)&inbuf[0x01], device_path, 0x27F);
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
if(outHandle) *outHandle = outbuf[1];
freeIobuf(iobuf);
return ret;
}
int FSA_RawClose(int fd, int device_handle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
inbuf[1] = device_handle;
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
}
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
freeIobuf(iobuf);
return ret;
}

View File

@ -1,10 +0,0 @@
#ifndef FSA_H
#define FSA_H
#include "types.h"
int FSA_RawOpen(int fd, const char* device_path, int* outHandle);
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
int FSA_RawClose(int fd, int device_handle);
#endif

View File

@ -1,156 +0,0 @@
/***************************************************************************
* 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 "svc.h"
#include "fsa.h"
#define SD_SEEPROM_SECTOR 0x4FF
#define BSP_MEMCPY ((void * (*)(void *, void *, unsigned int size))0xE600EA18)
static int writeEnabled = 0;
static int dirty = 0;
unsigned char seeprom_buffer[512] __attribute__((section(".seeprom_buffer")));
extern int orig_EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf);
static int SD_EEPROM_WriteAll(void)
{
int fsa = svcOpen("/dev/fsa", 0);
if(fsa < 0)
return fsa;
int fd;
int res = FSA_RawOpen(fsa, "/dev/sdcard01", &fd);
if(res >= 0)
{
void *buffer = svcAllocAlign(0xCAFF, 0x200, 0x40);
if(buffer)
{
// user global buffer for FSA to be able to access it
BSP_MEMCPY(buffer, seeprom_buffer, 0x200);
res = FSA_RawWrite(fsa, buffer, 0x200, 1, SD_SEEPROM_SECTOR, fd);
svcFree(0xCAFF, buffer);
}
else
res = -1;
FSA_RawClose(fsa, fd);
}
svcClose(fsa);
return res;
}
static void EEPROM_InitializeCache(int handle_index)
{
int i;
for(i = 0; i < 0x100; i++)
{
orig_EEPROM_SPI_ReadWord(handle_index, i, (unsigned short*)(seeprom_buffer + (i << 1)));
}
}
int EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf)
{
unsigned int offset = ((unsigned int)index) << 1;
// check for valid eeprom dump and initialize if none was on sd card
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
{
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
dirty = 1;
}
// don't redirect the drive key as it is specific for the drive on the wii u
// the seeprom key is the same for all wiiu's it seems so nothing to re-encrypt here
if(offset >= 0x80 && offset < 0x90)
{
return orig_EEPROM_SPI_ReadWord(handle_index, index, outbuf);
}
if(!outbuf || (offset >= 512))
{
return -5;
}
*outbuf = *(unsigned short*)(seeprom_buffer + offset);
if(dirty && SD_EEPROM_WriteAll() == 0)
{
dirty = 0;
}
return 0;
}
int EEPROM_SPI_WriteWord(int handle_index, unsigned char index, unsigned short data)
{
if(writeEnabled == 0)
{
return -5;
}
// check for valid eeprom dump and initialize if none was on sd card
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
{
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
}
unsigned int offset = ((unsigned int)index) << 1;
if(offset >= 512)
{
return -5;
}
*(unsigned short*)(seeprom_buffer + offset) = data;
dirty = 1;
if(SD_EEPROM_WriteAll() == 0)
{
dirty = 0;
}
return 0;
}
int EEPROM_WriteControl(int handle_index, int type)
{
if(type == 1)
{
writeEnabled = 0;
}
else if(type == 2)
{
writeEnabled = 1;
}
else if(type == 3)
{
// erase all -> skip that part...its actually never used but would be only a memset with 0xFF
}
else
{
return -4;
}
return 0;
}

View File

@ -1,9 +0,0 @@
.section ".text"
.arm
.globl orig_EEPROM_SPI_ReadWord
orig_EEPROM_SPI_ReadWord:
cmp r0, #0
ldr r3, [pc]
bx r3
.word 0xE600D090

View File

@ -1,21 +0,0 @@
#ifndef SVC_H
#define SVC_H
#include "types.h"
typedef struct
{
void* ptr;
u32 len;
u32 unk;
}iovec_s;
void* svcAlloc(u32 heapid, u32 size);
void* svcAllocAlign(u32 heapid, u32 size, u32 align);
void svcFree(u32 heapid, void* ptr);
int svcOpen(char* name, int mode);
int svcClose(int fd);
int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len);
int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector);
#endif

View File

@ -1,45 +0,0 @@
.section ".text"
.arm
.align 4
.global svcAlloc
.type svcAlloc, %function
svcAlloc:
.word 0xE7F027F0
bx lr
.global svcAllocAlign
.type svcAllocAlign, %function
svcAllocAlign:
.word 0xE7F028F0
bx lr
.global svcFree
.type svcFree, %function
svcFree:
.word 0xE7F029F0
bx lr
.global svcOpen
.type svcOpen, %function
svcOpen:
.word 0xE7F033F0
bx lr
.global svcClose
.type svcClose, %function
svcClose:
.word 0xE7F034F0
bx lr
.global svcIoctl
.type svcIoctl, %function
svcIoctl:
.word 0xE7F038F0
bx lr
.global svcIoctlv
.type svcIoctlv, %function
svcIoctlv:
.word 0xE7F039F0
bx lr

View File

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

View File

@ -1,80 +0,0 @@
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_' | 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)

View File

@ -1,26 +0,0 @@
OUTPUT_ARCH(arm)
SECTIONS
{
.text (0x10700000 + 0x000F8200) : {
_text_start = .;
*(.text*);
*(.rodata*);
}
_text_end = .;
.bss (0x10835000 + 0x1406554) : {
_bss_start = .;
*(.bss*);
*(COMMON);
}
.io_buffer : ALIGN(0x40) {
*(.io_buffer*);
}
_bss_end = .;
/DISCARD/ : {
*(*);
}
}

View File

@ -1,150 +0,0 @@
#include <stdio.h>
#include "types.h"
#include "devices.h"
#include "imports.h"
#include "sdio.h"
#include "text.h"
void * getMdDeviceById(int deviceId)
{
if(deviceId == DEVICE_ID_SDCARD_PATCHED)
{
return (void*)FS_MMC_SDCARD_STRUCT;
}
else if(deviceId == DEVICE_ID_MLC)
{
return (void*)FS_MMC_MLC_STRUCT;
}
return NULL;
}
int registerMdDevice_hook(void * md, int arg2, int arg3)
{
u32 *mdStruct = (u32*)md;
if((md != 0) && (mdStruct[2] == (u32)FS_MMC_SDCARD_STRUCT))
{
sdcard_lock_mutex();
FS_MMC_SDCARD_STRUCT[0x24/4] = FS_MMC_SDCARD_STRUCT[0x24/4] & (~0x20);
int result = FS_REGISTERMDPHYSICALDEVICE(md, arg2, arg3);
sdcard_unlock_mutex();
return result;
}
return FS_REGISTERMDPHYSICALDEVICE(md, arg2, arg3);
}
int getPhysicalDeviceHandle(u32 device)
{
u32 handleSize = 0x204;
u8 *handleBase = (u8*)(0x1091C2EC + device * handleSize);
u16 adrLow = (*(u16*)&handleBase[6]);
return ((device << 16) | adrLow);
}
//! read1(void *physical_device_info, int offset_high, int offset_low, int cnt, int block_size, void *data_outptr, void *callback, int callback_parameter)
int readWriteCallback_patch(int is_read, int offset_offset, int offset_low, int cnt, int block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
int result_arg = 0;
int result = sdcard_readwrite(is_read, data_outptr, cnt, block_size, offset_offset + offset_low, &result_arg, DEVICE_ID_SDCARD_PATCHED);
if((result == 0) && (callback != 0))
{
callback(result_arg, callback_parameter);
}
return result;
}
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! USB redirection
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static int usbReadWrite_patch(int is_read, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return readWriteCallback_patch(is_read, USB_BASE_SECTORS, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int usbRead_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return usbReadWrite_patch(SDIO_READ, offset_high, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int usbWrite_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return usbReadWrite_patch(SDIO_WRITE, offset_high, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! SDIO redirection
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static int sdcardReadWrite_patch(void *physical_device_info, int is_read, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
u32 offset_offset;
u32 *phys_dev = (u32*)physical_device_info;
if(phys_dev[0x14/4] != DEVICE_TYPE_SDCARD)
{
offset_offset = MLC_BASE_SECTORS;
}
else
{
offset_offset = 0;
}
return readWriteCallback_patch(is_read, offset_offset, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int sdcardRead_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return sdcardReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int sdcardWrite_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return sdcardReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! SLC redirection
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static int slcReadWrite_patch(void *physical_device_info, int is_read, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
u32 offset_offset;
u32 *phys_dev = (u32*)physical_device_info;
if(phys_dev[1] != 0)
{
// physical_device_info = 0x11C381CC
offset_offset = (u32)(((u64)SLC_BASE_SECTORS * (u64)SDIO_BYTES_PER_SECTOR) / SLC_BYTES_PER_SECTOR);
}
else
{
// physical_device_info = 0x11C37668
offset_offset = (u32)(((u64)SLCCMPT_BASE_SECTORS * (u64)SDIO_BYTES_PER_SECTOR) / SLC_BYTES_PER_SECTOR);
}
return readWriteCallback_patch(is_read, offset_offset, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int slcRead1_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return slcReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int slcWrite1_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
{
return slcReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int slcRead2_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, int ukn1, void *data_outptr, int ukn2, read_write_callback_t callback, int callback_parameter)
{
return slcReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}
int slcWrite2_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, int ukn1, void *data_outptr, int ukn2, read_write_callback_t callback, int callback_parameter)
{
return slcReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
}

View File

@ -1,110 +0,0 @@
#ifndef DEVICES_H_
#define DEVICES_H_
#define DEVICE_ID_SDCARD_REAL 0x43
#define DEVICE_ID_SDCARD_PATCHED 0xDA
#define DEVICE_ID_MLC 0xAB
#define SDIO_BYTES_PER_SECTOR 512
#define MLC_BYTES_PER_SECTOR 512
#define SLC_BYTES_PER_SECTOR 2048
#define SLC_BASE_SECTORS (0x000500)
#define SLCCMPT_BASE_SECTORS (0x100500)
#define MLC_BASE_SECTORS (0x200500)
#define USB_BASE_SECTORS (0x2720000)
#define SYSLOG_BASE_SECTORS (0x6D00000)
#define DUMPDATA_BASE_SECTORS (SYSLOG_BASE_SECTORS + (0x40000 / SDIO_BYTES_PER_SECTOR))
#define SLC_SECTOR_COUNT 0x40000
#define MLC_8GB_SECTOR_COUNT 0xE90000
#define MLC_32GB_SECTOR_COUNT 0x3A3E000 //0x3A20000
#define MLC_NAND_TYPE_32GB 0
#define MLC_NAND_TYPE_8GB 1
#define NAND_DUMP_SIGNATURE_SECTOR 0x01
#define NAND_DUMP_SIGNATURE 0x4841585844554d50ULL // HAXXDUMP
#define NAND_DESC_TYPE_SLC 0x534c4320 // 'SLC '
#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
u32 base_sector; // base sector of dump
u32 sector_count; // sector count in SDIO sectors
} __attribute__((packed))stdio_nand_desc_t;
typedef struct _sdio_nand_signature_sector_t
{
u64 signature; // HAXXDUMP
stdio_nand_desc_t nand_descriptions[3];
} __attribute__((packed)) sdio_nand_signature_sector_t;
typedef void (*read_write_callback_t)(int, int);
int getPhysicalDeviceHandle(u32 device);
int slcRead1_original(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter);
int sdcardRead_original(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter);
#endif // DEVICES_H_

View File

@ -1,322 +0,0 @@
#include <stdio.h>
#include "types.h"
#include "imports.h"
#include "devices.h"
#include "sdio.h"
#include "mlcio.h"
#include "fat32_format.h"
#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")));
//! this one is required for the read function
static void slc_read_callback(int result, int priv)
{
int *private_data = (int*)priv;
private_data[1] = result;
FS_SVC_RELEASEMUTEX(private_data[0]);
}
static int srcRead(void* deviceHandle, void *data_ptr, u32 offset, u32 sectors, int * result_array)
{
int readResult = slcRead1_original(deviceHandle, 0, offset, sectors, SLC_BYTES_PER_SECTOR, data_ptr, slc_read_callback, (int)result_array);
if(readResult == 0)
{
// wait for process to finish
FS_SVC_ACQUIREMUTEX(result_array[0], 0);
readResult = result_array[1];
}
return readResult;
}
void slc_dump(void *deviceHandle, const char* device, u32 base_sectors, int y_offset)
{
//also create a mutex for synchronization with end of operation...
int sync_mutex = FS_SVC_CREATEMUTEX(1, 1);
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
int result_array[2];
result_array[0] = sync_mutex;
u32 offset = 0;
int readResult = 0;
int writeResult = 0;
int retry = 0;
u32 readSize = sizeof(io_buffer) / SLC_BYTES_PER_SECTOR;
FS_SLEEP(1000);
do
{
// don't print single steps in between, just if they have an error or every 0x80 sectors
if((readSize == (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR)) || (retry > 0))
{
_printf(20, y_offset, "%s = %08X / 40000, read code %08X, write code %08X, retry %d", device, offset, readResult, writeResult, retry);
}
//! set flash erased byte to buffer
FS_MEMSET(io_buffer, 0xff, sizeof(io_buffer));
//readResult = readSlc(io_buffer, offset, (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR), deviceHandle);
readResult = srcRead(deviceHandle, io_buffer, offset, readSize, result_array);
//! retry 2 times as there are read failures in several places
if((readResult != 0) && (retry < 2))
{
readSize = 1;
FS_SLEEP(10);
retry++;
}
else
{
retry = 0;
while(1)
{
FS_SLEEP(10);
writeResult = sdcard_readwrite(SDIO_WRITE, io_buffer, (readSize * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR)), SDIO_BYTES_PER_SECTOR, base_sectors, NULL, DEVICE_ID_SDCARD_PATCHED);
if((writeResult == 0) || (retry >= 2))
{
retry = 0;
base_sectors += (readSize * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR));
offset += readSize;
// if we did single sector reads and got to a point where we can do multiple reads -> switch to multiple sector reads
if((offset % (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR)) == 0)
{
readSize = sizeof(io_buffer) / SLC_BYTES_PER_SECTOR;
}
break;
}
else
{
retry++;
}
}
}
}
while (offset < SLC_SECTOR_COUNT);
FS_SVC_DESTROYMUTEX(sync_mutex);
// last print to show "done"
_printf(20, y_offset, "%s = %08X / 40000, read code %08X, write code %08X, retry %d", device, offset, readResult, writeResult, retry);
}
void mlc_dump(u32 base_sector, u32 mlc_end)
{
u32 offset = 0;
int retry = 0;
int mlc_result = 0;
int callback_result = 0;
int write_result = 0;
int print_counter = 0;
do
{
//! print only every 4th time
if(print_counter == 0)
{
print_counter = 4;
_printf(20, 70, "mlc = %08X / %08X, mlc res %08X, sd res %08X, retry %d", offset, mlc_end, mlc_result, write_result, retry);
}
else
{
--print_counter;
}
//! set flash erased byte to buffer
FS_MEMSET(io_buffer, 0xff, sizeof(io_buffer));
mlc_result = sdcard_readwrite(SDIO_READ, io_buffer, (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR), MLC_BYTES_PER_SECTOR, offset, &callback_result, DEVICE_ID_MLC);
if((mlc_result == 0) && (callback_result != 0))
{
mlc_result = callback_result;
}
//! retry 5 times as there are read failures in several places
if((mlc_result != 0) && (retry < 5))
{
FS_SLEEP(100);
retry++;
print_counter = 0; // print errors directly
}
else
{
write_result = sdcard_readwrite(SDIO_WRITE, io_buffer, (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR), SDIO_BYTES_PER_SECTOR, base_sector + offset, NULL, DEVICE_ID_SDCARD_PATCHED);
if((write_result == 0) || (retry >= 5))
{
retry = 0;
offset += (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR);
}
else
{
FS_SLEEP(100);
retry++;
print_counter = 0; // print errors directly
}
}
}
while(offset < mlc_end); //! TODO: make define MLC32_SECTOR_COUNT
// last print to show "done"
_printf(20, 70, "mlc = %08X / %08X, mlc res %08X, sd res %08X, retry %d", offset, mlc_end, mlc_result, write_result, retry);
}
int check_nand_type(void)
{
//! check if MLC size is > 8GB
if( FS_MMC_MLC_STRUCT[0x30/4] > 0x1000000)
{
return MLC_NAND_TYPE_32GB;
}
else
{
return MLC_NAND_TYPE_8GB;
}
}
int check_nand_dump(void)
{
u32 mlc_sector_count = FS_MMC_MLC_STRUCT[0x30/4];
int signature_correct = 0;
sdio_nand_signature_sector_t * sign_sect = (sdio_nand_signature_sector_t*)io_buffer;
memset(sign_sect, 0, SDIO_BYTES_PER_SECTOR);
sdcard_readwrite(SDIO_READ, sign_sect, 1, SDIO_BYTES_PER_SECTOR, NAND_DUMP_SIGNATURE_SECTOR, NULL, DEVICE_ID_SDCARD_PATCHED);
signature_correct = (sign_sect->signature == NAND_DUMP_SIGNATURE);
memset(io_buffer, 0, SDIO_BYTES_PER_SECTOR);
sdcard_readwrite(SDIO_READ, io_buffer, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
return signature_correct && CheckFAT32PartitionOffset(io_buffer, MLC_BASE_SECTORS + mlc_sector_count);
}
static void wait_format_confirmation(void)
{
int timeout = 600;
//"Press the POWER button SD then , else the console will reboot in %u seconds."
while(1)
{
_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(svcCustomKernelCommand(KERNEL_READ32, LT_GPIO_IN) & GPIO_IN_POWER_BUTTON)
{
break;
}
if(--timeout == 0)
{
FS_SLEEP(1000);
svcShutdown(SHUTDOWN_TYPE_REBOOT);
}
FS_SLEEP(100);
}
// clear the lines
clearLine(30, 0x000000FF);
clearLine(40, 0x000000FF);
}
void dump_nand_complete()
{
wait_format_confirmation();
mlc_init();
FS_SLEEP(1000);
int nand_type = check_nand_type();
u32 sdio_sector_count = FS_MMC_SDCARD_STRUCT[0x30/4];
u32 mlc_sector_count = FS_MMC_MLC_STRUCT[0x30/4];
u32 fat32_partition_offset = (MLC_BASE_SECTORS + mlc_sector_count);
_printf(20, 30, "Detected %d GB MLC NAND type.", (nand_type == MLC_NAND_TYPE_8GB) ? 8 : 32);
if(sdio_sector_count < fat32_partition_offset)
{
_printf(20, 40, "SD card too small! Required sectors %u > available %u.", fat32_partition_offset, sdio_sector_count);
FS_SLEEP(3000);
svcShutdown(SHUTDOWN_TYPE_REBOOT);
}
if( FormatSDCard(fat32_partition_offset, sdio_sector_count) < 0 )
{
FS_SLEEP(3000);
svcShutdown(SHUTDOWN_TYPE_REBOOT);
}
slc_dump(FS_SLC_PHYS_DEV_STRUCT, "slc ", SLC_BASE_SECTORS, 50);
slc_dump(FS_SLCCMPT_PHYS_DEV_STRUCT, "slccmpt", SLCCMPT_BASE_SECTORS, 60);
mlc_dump(MLC_BASE_SECTORS, mlc_sector_count);
//! write marker to SD card from which we can auto detect NAND dump
//! we can actually use that for settings
sdio_nand_signature_sector_t * sign_sect = (sdio_nand_signature_sector_t*)io_buffer;
memset(sign_sect, 0, SDIO_BYTES_PER_SECTOR);
sign_sect->signature = NAND_DUMP_SIGNATURE;
sign_sect->nand_descriptions[0].nand_type = NAND_DESC_TYPE_SLC;
sign_sect->nand_descriptions[0].base_sector = SLC_BASE_SECTORS;
sign_sect->nand_descriptions[0].sector_count = SLC_SECTOR_COUNT * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
sign_sect->nand_descriptions[1].nand_type = NAND_DESC_TYPE_SLCCMPT;
sign_sect->nand_descriptions[1].base_sector = SLCCMPT_BASE_SECTORS;
sign_sect->nand_descriptions[1].sector_count = SLC_SECTOR_COUNT * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
sign_sect->nand_descriptions[2].nand_type = NAND_DESC_TYPE_MLC;
sign_sect->nand_descriptions[2].base_sector = MLC_BASE_SECTORS;
sign_sect->nand_descriptions[2].sector_count = mlc_sector_count * (MLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
sdcard_readwrite(SDIO_WRITE, io_buffer, 1, SDIO_BYTES_PER_SECTOR, NAND_DUMP_SIGNATURE_SECTOR, NULL, DEVICE_ID_SDCARD_PATCHED);
_printf(20, 80, "Complete! -> rebooting into sysNAND...");
FS_SLEEP(3000);
svcShutdown(SHUTDOWN_TYPE_REBOOT);
}
#if 0
// debug and not used at the moment
void dump_data(void* data_ptr, u32 size)
{
static u32 dumpdata_offset = 0;
u32 num_sectors = size >> 9; // size / SDIO_BYTES_PER_SECTOR but faster ;)
if (num_sectors == 0)
num_sectors = 1;
sdcard_readwrite(SDIO_WRITE, data_ptr, num_sectors, SDIO_BYTES_PER_SECTOR, DUMPDATA_BASE_SECTORS + dumpdata_offset, NULL, DEVICE_ID_SDCARD_PATCHED);
dumpdata_offset += num_sectors;
}
void dump_lots_data(u8* addr, u32 size)
{
u32 cur_size;
u32 size_remaining = size;
u8* cur_addr = addr;
do
{
cur_size = sizeof(io_buffer);
if (cur_size > size_remaining)
cur_size = size_remaining;
FS_MEMCPY(io_buffer, cur_addr, cur_size);
dump_data(io_buffer, cur_size);
cur_addr += cur_size;
size_remaining -= cur_size;
}
while (cur_size != 0);
}
void dump_syslog()
{
FS_MEMCPY(io_buffer, *(void**)0x05095ECC, sizeof(io_buffer));
sdcard_readwrite(SDIO_WRITE, io_buffer, sizeof(io_buffer) / SDIO_BYTES_PER_SECTOR, SDIO_BYTES_PER_SECTOR, SYSLOG_BASE_SECTORS, NULL, DEVICE_ID_SDCARD_PATCHED);
}
#endif

View File

@ -1,15 +0,0 @@
#ifndef _DUMPER_H_
#define _DUMPER_H_
//! debug dumps
void dump_syslog();
void dump_data(void* data_ptr, u32 size);
void dump_lots_data(u8* addr, u32 size);
int check_nand_type(void);
int check_nand_dump(void);
void slc_dump(int deviceId, const char* format, u32 base_sectors);
void mlc_dump(u32 base_sector, u32 mlc_end);
void dump_nand_complete();
#endif // _DUMPER_H_

View File

@ -1,326 +0,0 @@
#include <stdio.h>
#include "types.h"
#include "imports.h"
#include "devices.h"
#include "sdio.h"
#include "text.h"
extern unsigned char io_buffer[0x40000];
#define PARTITION_TYPE_FAT32 0x0c
#define MAX_PARTITIONS 32 /* Maximum number of partitions that can be found */
#define MAX_MOUNTS 10 /* Maximum number of mounts available at one time */
#define MAX_SYMLINK_DEPTH 10 /* Maximum search depth when resolving symbolic links */
#define MBR_SIGNATURE 0x55AA
#define EBR_SIGNATURE MBR_SIGNATURE
#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */
#define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */
#define PARTITION_TYPE_GPT 0xEE /* Indicates that a GPT header is available */
typedef struct _PARTITION_RECORD {
u8 status; /* Partition status; see above */
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
u8 type; /* Partition type; see above */
u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */
u32 lba_start; /* Local block address to first sector of partition */
u32 block_count; /* Number of blocks in partition */
} __attribute__((__packed__)) PARTITION_RECORD;
typedef struct _MASTER_BOOT_RECORD {
u8 code_area[446]; /* Code area; normally empty */
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
u16 signature; /* MBR signature; 0xAA55 */
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
typedef struct tagFAT_BOOTSECTOR32
{
// Common fields.
u8 sJmpBoot[3];
u8 sOEMName[8];
u16 wBytsPerSec;
u8 bSecPerClus;
u16 wRsvdSecCnt;
u8 bNumFATs;
u16 wRootEntCnt;
u16 wTotSec16;
u8 bMedia;
u16 wFATSz16;
u16 wSecPerTrk;
u16 wNumHeads;
u32 dHiddSec;
u32 dTotSec32;
// Fat 32/16 only
u32 dFATSz32;
u16 wExtFlags;
u16 wFSVer;
u32 dRootClus;
u16 wFSInfo;
u16 wBkBootSec;
u8 Reserved[12];
u8 bDrvNum;
u8 Reserved1;
u8 bBootSig; // == 0x29 if next three fields are ok
u32 dBS_VolID;
u8 sVolLab[11];
u8 sBS_FilSysType[8];
} __attribute__((__packed__)) FAT_BOOTSECTOR32;
typedef struct {
u32 dLeadSig;
u8 sReserved1[480];
u32 dStrucSig;
u32 dFree_Count;
u32 dNxt_Free;
u8 sReserved2[12];
u32 dTrailSig;
} __attribute__((__packed__)) FAT_FSINFO;
static inline u8 get_sectors_per_cluster (u64 DiskSizeBytes)
{
u8 ret = 0x01; // 1 sector per cluster
u32 DiskSizeMB = DiskSizeBytes/(1024*1024);
// 512 MB to 8,191 MB 4 KB
if (DiskSizeMB > 512)
ret = 0x8;
// 8,192 MB to 16,383 MB 8 KB
if (DiskSizeMB > 8192)
ret = 0x10;
// 16,384 MB to 32,767 MB 16 KB
if (DiskSizeMB > 16384)
ret = 0x20; // ret = 0x20;
// Larger than 32,768 MB 32 KB
if (DiskSizeMB > 32768)
ret = 0x40; // ret = 0x40;
return ret;
}
static inline u32 MakeVolumeID()
{
// we dont have time yet so for now its fixed
//time_t rawtime = time(0);
//struct tm * timeinfo = localtime(&rawtime);
//u16 hi = le16(timeinfo->tm_mday + (timeinfo->tm_mon << 8) + (timeinfo->tm_sec << 8));
//u16 lo = le16((timeinfo->tm_hour << 8) + timeinfo->tm_min + timeinfo->tm_year + 1900);
u16 hi = 0x0BAD;
u16 lo = 0xBABE;
return (lo + (hi << 16));
}
int FormatToFAT32(u32 lba, u32 sec_count)
{
if(sec_count < 0xFFFF)
{
_printf(20, 40, "Not enough sectors for FAT32");
return -1;
}
int BytesPerSect = SDIO_BYTES_PER_SECTOR;
u16 ReservedSectCount = 32;
u8 NumFATs = 2;
memset(io_buffer, 0, BytesPerSect*18);
FAT_BOOTSECTOR32 * FAT32BootSect = (FAT_BOOTSECTOR32 *) (io_buffer+16*BytesPerSect);
FAT_FSINFO * FAT32FsInfo = (FAT_FSINFO*) (io_buffer+17*BytesPerSect);
// fill out the boot sector and fs info
FAT32BootSect->sJmpBoot[0] = 0xEB;
FAT32BootSect->sJmpBoot[1] = 0x5A;
FAT32BootSect->sJmpBoot[2] = 0x90;
memcpy(FAT32BootSect->sOEMName, "MSWIN4.1", 8);
FAT32BootSect->wBytsPerSec = le16(BytesPerSect);
u8 SectorsPerCluster = get_sectors_per_cluster((u64) sec_count * (u64) BytesPerSect);
FAT32BootSect->bSecPerClus = SectorsPerCluster;
FAT32BootSect->wRsvdSecCnt = le16(ReservedSectCount);
FAT32BootSect->bNumFATs = NumFATs;
FAT32BootSect->wRootEntCnt = 0;
FAT32BootSect->wTotSec16 = 0;
FAT32BootSect->bMedia = 0xF8;
FAT32BootSect->wFATSz16 = 0;
FAT32BootSect->wSecPerTrk = le16(63); //SectorsPerTrack;
FAT32BootSect->wNumHeads = le16(255); //TracksPerCylinder;
FAT32BootSect->dHiddSec = le32(lba); //HiddenSectors;
FAT32BootSect->dTotSec32 = le32(sec_count);
// This is based on
// http://hjem.get2net.dk/rune_moeller_barnkob/filesystems/fat.html
u32 FatSize = (4*(sec_count-ReservedSectCount)/((SectorsPerCluster*BytesPerSect)+(4*NumFATs)))+1;
FAT32BootSect->dFATSz32 = le32(FatSize);
FAT32BootSect->wExtFlags = 0;
FAT32BootSect->wFSVer = 0;
FAT32BootSect->dRootClus = le32(2);
FAT32BootSect->wFSInfo = le16(1);
FAT32BootSect->wBkBootSec = le16(6); //BackupBootSect
FAT32BootSect->bDrvNum = 0x80;
FAT32BootSect->Reserved1 = 0;
FAT32BootSect->bBootSig = 0x29;
FAT32BootSect->dBS_VolID = MakeVolumeID();
memcpy(FAT32BootSect->sVolLab, "NO NAME ", 11);
memcpy(FAT32BootSect->sBS_FilSysType, "FAT32 ", 8);
((u8 *)FAT32BootSect)[510] = 0x55; //Boot Record Signature
((u8 *)FAT32BootSect)[511] = 0xAA; //Boot Record Signature
// FSInfo sect signatures
FAT32FsInfo->dLeadSig = le32(0x41615252);
FAT32FsInfo->dStrucSig = le32(0x61417272);
FAT32FsInfo->dTrailSig = le32(0xaa550000);
((u8 *)FAT32FsInfo)[510] = 0x55; //Boot Record Signature
((u8 *)FAT32FsInfo)[511] = 0xAA; //Boot Record Signature
// First FAT Sector
u32 FirstSectOfFat[3];
FirstSectOfFat[0] = le32(0x0ffffff8); // Reserved cluster 1 media id in low byte
FirstSectOfFat[1] = le32(0x0fffffff); // Reserved cluster 2 EOC
FirstSectOfFat[2] = le32(0x0fffffff); // end of cluster chain for root dir
u32 UserAreaSize = sec_count - ReservedSectCount - (NumFATs*FatSize);
u32 ClusterCount = UserAreaSize/SectorsPerCluster;
if (ClusterCount > 0x0FFFFFFF)
{
_printf(20, 40, "This drive has more than 2^28 clusters. Partition might be too small.");
return -1;
}
if (ClusterCount < 65536)
{
_printf(20, 40, "FAT32 must have at least 65536 clusters");
return -1;
}
u32 FatNeeded = (ClusterCount * 4 + (BytesPerSect-1))/BytesPerSect;
if (FatNeeded > FatSize)
{
_printf(20, 40, "This drive is too big, %u > %u", FatNeeded, FatSize);
return -1;
}
// fix up the FSInfo sector
FAT32FsInfo->dFree_Count = le32((UserAreaSize/SectorsPerCluster)-1);
FAT32FsInfo->dNxt_Free = le32(3); // clusters 0-1 resered, we used cluster 2 for the root dir
/** Now all is done and we start writting **/
// First zero out ReservedSect + FatSize * NumFats + SectorsPerCluster
u32 SystemAreaSize = (ReservedSectCount+(NumFATs*FatSize) + SectorsPerCluster);
u32 done = 0;
// Read the first sector on the device
while(SystemAreaSize > 0)
{
int write = SystemAreaSize < 16 ? SystemAreaSize : 16;
int result = sdcard_readwrite(SDIO_WRITE, io_buffer, write, SDIO_BYTES_PER_SECTOR, lba+done, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "Cannot write to the drive.");
return -1;
}
SystemAreaSize -= write;
done += write;
}
for (int i = 0; i < 2; i++)
{
u32 SectorStart = (i == 0) ? lba : lba+6; //BackupBootSect
int result = sdcard_readwrite(SDIO_WRITE, FAT32BootSect, 1, SDIO_BYTES_PER_SECTOR, SectorStart, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "Cannot write to the drive.");
return -1;
}
result = sdcard_readwrite(SDIO_WRITE, FAT32FsInfo, 1, SDIO_BYTES_PER_SECTOR, SectorStart+1, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "Cannot write to the drive.");
return -1;
}
}
memcpy(io_buffer, FirstSectOfFat, sizeof(FirstSectOfFat));
// Write the first fat sector in the right places
for (int i = 0; i < NumFATs; i++)
{
u32 SectorStart = lba + ReservedSectCount + (i * FatSize);
int result = sdcard_readwrite(SDIO_WRITE, io_buffer, 1, SDIO_BYTES_PER_SECTOR, SectorStart, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "Cannot write to the drive.");
return -1;
}
}
return 0;
}
int CheckFAT32PartitionOffset(u8 * mbr_buf, u32 partition_offset)
{
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)mbr_buf;
return (mbr->signature == MBR_SIGNATURE) && (le32(mbr->partitions[0].lba_start) >= partition_offset);
}
int FormatSDCard(u32 partition_offset, u32 total_sectors)
{
_printf(20, 40, "Formatting SD card....");
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)io_buffer;
memset(mbr, 0, SDIO_BYTES_PER_SECTOR);
int result = sdcard_readwrite(SDIO_READ, mbr, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "SD card read failed %i", result);
return result;
}
u32 lba_start = partition_offset;
result = FormatToFAT32(lba_start, total_sectors - partition_offset);
if(result != 0)
return result;
memset(mbr, 0, sizeof(MASTER_BOOT_RECORD));
mbr->signature = MBR_SIGNATURE;
// setup primary FAT32 partition
mbr->partitions[0].status = PARTITION_BOOTABLE; // set activate
mbr->partitions[0].chs_start[0] = mbr->partitions[0].chs_end[0] = 0xFE;
mbr->partitions[0].chs_start[1] = mbr->partitions[0].chs_end[1] = 0xFF;
mbr->partitions[0].chs_start[2] = mbr->partitions[0].chs_end[2] = 0xFF;
mbr->partitions[0].type = PARTITION_TYPE_FAT32;
mbr->partitions[0].lba_start = le32(lba_start);
mbr->partitions[0].block_count = le32((total_sectors - partition_offset));
result = sdcard_readwrite(SDIO_WRITE, mbr, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
if(result != 0)
{
_printf(20, 40, "SD card write failed %i", result);
}
else
{
_printf(20, 40, "Format of SD card finished successfully", result);
}
return result;
}

View File

@ -1,7 +0,0 @@
#ifndef _FAT32_FORMAT_H_
#define _FAT32_FORMAT_H_
int CheckFAT32PartitionOffset(u8 * mbr, u32 partition_offset);
int FormatSDCard(u32 partition_offset, u32 total_sectors);
#endif // _FAT32_FORMAT_H_

View File

@ -1,49 +0,0 @@
const unsigned char font_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
};

View File

@ -1 +0,0 @@
extern const u8 font_bin[];

View File

@ -1,222 +0,0 @@
/***************************************************************************
* 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;
}
*/

View File

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

View File

@ -1,101 +0,0 @@
#############################################################################################
# FS main thread hook
#############################################################################################
.extern createDevThread_entry
.globl createDevThread_hook
createDevThread_hook:
push {r0,r1,lr}
ldr r0, [r4, #0x8]
mov r1, r7
bl createDevThread_entry
pop {r0,r1,lr}
# restore original instruction
pop {r4-r8,pc}
#############################################################################################
# devices handle hooks
#############################################################################################
.extern getMdDeviceById
.globl getMdDeviceById_hook
getMdDeviceById_hook:
mov r4, r0
push {lr}
bl getMdDeviceById
pop {lr}
cmp r0, #0
moveq r0, r4
bxeq lr
pop {r4,r5,pc}
#############################################################################################
# syslog hook
#############################################################################################
.globl syslogOutput_hook
syslogOutput_hook:
# push {r0,lr}
# bl dump_syslog
# pop {r0,lr}
# restore original instruction
pop {r4-r8,r10,pc}
#############################################################################################
# Original NAND read functions
#############################################################################################
.globl slcRead1_original
slcRead1_original:
push {r4-r8,lr}
ldr r4, [pc]
bx r4
.word 0x107B9990
.globl sdcardRead_original
sdcardRead_original:
push {r4,lr}
ldr r4, [pc]
bx r4
.word 0x107BDDD4
#############################################################################################
# FSA functions
#############################################################################################
.globl FSA_MakeQuota_asm_hook
FSA_MakeQuota_asm_hook:
mov r1, r5
b FSA_MakeQuota_hook
#############################################################################################
# DEBUG STUFF
#############################################################################################
# # # # # # # # # #
# DEBUG STUFF #
# # # # # # # # # #
#mlcRead1_dbg:
# mlcRead1_dbg_stackframe equ (4*6)
# mov r12, r0
# push {r0-r3,r12,lr}
# adr r0, mlcRead1_dbg_format
# ldr r1, [sp, #mlcRead1_dbg_stackframe+9*4]
# bl FS_SYSLOG_OUTPUT
# pop {r0-r3,lr,pc} # replaces mov lr, r0
# mlcRead1_dbg_format:
# .ascii "mlcRead1 : %08X %08X %08X"
# .byte 0x0a
# .byte 0x00
# .align 0x4
#
#mlcRead1_end_hook:
# mlcRead1_end_hook_stackframe equ (4*10)
# push {r0}
# mov r0, #50
# bl FS_SLEEP
# ldr r0, =sdcard_read_buffer
# ldr r1, [sp, #mlcRead1_end_hook_stackframe+4*1]
# mov r2, #0x200
# bl FS_MEMCPY
# ldr r0, =sdcard_read_buffer
# str r6, [r0]
# mov r1, #0x200
# bl dump_data
# pop {r0,r4-r11,pc}

View File

@ -1,9 +0,0 @@
#ifndef HARDWARE_REGISTERS_H_
#define HARDWARE_REGISTERS_H_
#define LT_GPIO_IN 0x0d8000e8
#define GPIO_IN_POWER_BUTTON 0x01
#endif // HARDWARE_REGISTERS_H_

View File

@ -1,38 +0,0 @@
#ifndef IMPORTS_H_
#define IMPORTS_H_
#define FS_IOS_SHUTDOWN ((void (*)(int))0x107F6C94)
#define FS_SVC_CREATEMUTEX ((int (*)(int, int))0x107F6BBC)
#define FS_SVC_ACQUIREMUTEX ((int (*)(int, int))0x107F6BC4)
#define FS_SVC_RELEASEMUTEX ((int (*)(int))0x107F6BCC)
#define FS_SVC_DESTROYMUTEX ((int (*)(int))0x107F6BD4)
#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, 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)
#define FS_REGISTERMDPHYSICALDEVICE ((int (*)(void*, int, int))0x10718860)
#define memcpy FS_MEMCPY
#define memset FS_MEMSET
#define FS_MMC_SDCARD_STRUCT ((vu32*)0x1089B9F8)
#define FS_MMC_MLC_STRUCT ((vu32*)0x1089B948)
#define FS_MLC_PHYS_DEV_STRUCT ((void*)0x11C3A14C)
#define FS_SLC_PHYS_DEV_STRUCT ((void*)0x11C381CC)
#define FS_SLCCMPT_PHYS_DEV_STRUCT ((void*)0x11C37668)
#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8)))
#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16)))
#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
#endif // IMPORTS_H_

View File

@ -1,62 +0,0 @@
#include "text.h"
#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"
void createDevThread_entry(int node_type, u32 *dev_handles)
{
FS_SYSLOG_OUTPUT("FSA: %s thread created\n", (char*)dev_handles[0]);
if(node_type == NODE_TYPE_DEV_MMC)
{
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)
{
// 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!");
dump_nand_complete();
}
}
}

View File

@ -1,11 +0,0 @@
#include "types.h"
#include "imports.h"
void mlc_init(void)
{
FS_MMC_MLC_STRUCT[0x24/4] = FS_MMC_MLC_STRUCT[0x24/4] | 0x20;
FS_MMC_MLC_STRUCT[0x28/4] = FS_MMC_MLC_STRUCT[0x28/4] & (~0x04);
}

View File

@ -1,6 +0,0 @@
#ifndef _MLCIO_H_
#define _MLCIO_H_
void mlc_init(void);
#endif // _MLCIO_H_

View File

@ -1,107 +0,0 @@
#include "types.h"
#include "imports.h"
static int sdcard_access_mutex = 0;
static u32 dumpdata_offset = 0;
typedef struct _sd_command_block_t
{
u32 cnt;
u32 block_size;
u32 command_type;
void * data_ptr;
u64 offset;
void *callback;
void *callback_arg;
int minus_one;
} __attribute__((packed)) sd_command_block_t;
void sdcard_init(void)
{
// this should run *after* /dev/mmc thread is created
// first we create our synchronization stuff
sdcard_access_mutex = FS_SVC_CREATEMUTEX(1, 1);
dumpdata_offset = 0;
// then we sleep until /dev/mmc is done initializing sdcard (TODO : better synchronization here)
FS_SLEEP(1000);
// finally we set some flags to indicate sdcard is ready for use
FS_MMC_SDCARD_STRUCT[0x24/4] = FS_MMC_SDCARD_STRUCT[0x24/4] | 0x20;
FS_MMC_SDCARD_STRUCT[0x28/4] = FS_MMC_SDCARD_STRUCT[0x28/4] & (~0x04);
}
static void sdcard_readwrite_callback(void *priv_data, int result)
{
int *private_data = (int*)priv_data;
private_data[1] = result;
FS_SVC_RELEASEMUTEX(private_data[0]);
}
void sdcard_lock_mutex(void)
{
FS_SVC_ACQUIREMUTEX(sdcard_access_mutex, 0);
}
void sdcard_unlock_mutex(void)
{
FS_SVC_RELEASEMUTEX(sdcard_access_mutex);
}
int sdcard_readwrite(int is_read, void *data, u32 cnt, u32 block_size, u32 offset_blocks, int * out_callback_arg, int device_id)
{
// first of all, grab sdcard mutex
sdcard_lock_mutex();
//also create a mutex for synchronization with end of operation...
int sync_mutex = FS_SVC_CREATEMUTEX(1, 1);
// ...and acquire it
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
// block_size needs to be equal to sector_size (0x200)
while(block_size > 0x200)
{
block_size >>= 1;
cnt <<= 1;
offset_blocks <<= 1;
}
// build rw command paramstruct
sd_command_block_t command;
command.cnt = cnt;
command.block_size = block_size;
command.command_type = (is_read ? 0x03 : 0x00);
command.data_ptr = data;
command.offset = offset_blocks;
command.callback = 0x00;
command.callback_arg = 0x00;
command.minus_one = (u32)-1;
// setup parameters
int private_data[2];
private_data[0] = sync_mutex;
private_data[1] = 0;
// call readwrite function
int result = FS_SDIO_DOREADWRITECOMMAND(device_id, &command, offset_blocks, sdcard_readwrite_callback, (void*)private_data);
if(result == 0)
{
// wait for callback to give the go-ahead
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
if(out_callback_arg)
{
*out_callback_arg = private_data[1];
}
}
// finally, release sdcard mutexes
FS_SVC_DESTROYMUTEX(sync_mutex);
sdcard_unlock_mutex();
return result;
}

View File

@ -1,12 +0,0 @@
#ifndef _SDIO_H_
#define _SDIO_H_
#define SDIO_WRITE 0
#define SDIO_READ 1
void sdcard_init(void);
void sdcard_lock_mutex(void);
void sdcard_unlock_mutex(void);
int sdcard_readwrite(int is_read, void *data, u32 cnt, u32 block_size, u32 offset_blocks, int * out_callback_arg, int device_id);
#endif // _SDIO_H_

View File

@ -1,29 +0,0 @@
#ifndef SVC_H
#define SVC_H
#include "types.h"
#define SHUTDOWN_TYPE_POWER_OFF 0
#define SHUTDOWN_TYPE_REBOOT 1
typedef struct
{
void* ptr;
u32 len;
u32 unk;
}iovec_s;
void* svcAlloc(u32 heapid, u32 size);
void* svcAllocAlign(u32 heapid, u32 size, u32 align);
void svcFree(u32 heapid, void* ptr);
int svcOpen(char* name, int mode);
int svcClose(int fd);
int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len);
int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector);
int svcInvalidateDCache(void* address, u32 size);
int svcFlushDCache(void* address, u32 size);
void svcShutdown(int shutdown_type);
int svcCustomKernelCommand(u32 command, ...);
#endif

View File

@ -1,68 +0,0 @@
.arm
.align 4
.global svcAlloc
.type svcAlloc, %function
svcAlloc:
.word 0xE7F027F0
bx lr
.global svcAllocAlign
.type svcAllocAlign, %function
svcAllocAlign:
.word 0xE7F028F0
bx lr
.global svcFree
.type svcFree, %function
svcFree:
.word 0xE7F029F0
bx lr
.global svcOpen
.type svcOpen, %function
svcOpen:
.word 0xE7F033F0
bx lr
.global svcClose
.type svcClose, %function
svcClose:
.word 0xE7F034F0
bx lr
.global svcIoctl
.type svcIoctl, %function
svcIoctl:
.word 0xE7F038F0
bx lr
.global svcIoctlv
.type svcIoctlv, %function
svcIoctlv:
.word 0xE7F039F0
bx lr
.global svcInvalidateDCache
.type svcInvalidateDCache, %function
svcInvalidateDCache:
.word 0xE7F051F0
bx lr
.global svcFlushDCache
.type svcFlushDCache, %function
svcFlushDCache:
.word 0xE7F052F0
bx lr
.global svcShutdown
.type svcShutdown, %function
svcShutdown:
.word 0xE7F072F0
bx lr
.global svcCustomKernelCommand
.type svcCustomKernelCommand, %function
svcCustomKernelCommand:
.word 0xE7F081F0
bx lr

View File

@ -1,90 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "imports.h"
#include "types.h"
#include "font_bin.h"
#define FRAMEBUFFER_ADDRESS (0x14000000+0x38C0000)
#define FRAMEBUFFER_STRIDE (0xE00)
#define FRAMEBUFFER_STRIDE_WORDS (FRAMEBUFFER_STRIDE >> 2)
#define CHAR_SIZE_X (8)
#define CHAR_SIZE_Y (8)
u32* const framebuffer = (u32*)FRAMEBUFFER_ADDRESS;
void clearScreen(u32 color)
{
int i;
for(i = 0; i < ((FRAMEBUFFER_STRIDE * 504)/4); i++)
{
framebuffer[i] = color;
}
}
void clearLine(int y, u32 color)
{
u32* fb = &framebuffer[y * FRAMEBUFFER_STRIDE_WORDS];
u32* fb_end = &framebuffer[(y+CHAR_SIZE_Y) * FRAMEBUFFER_STRIDE_WORDS];
while(fb < fb_end)
{
*fb = color;
fb++;
}
}
void drawCharacter(char c, int x, int y)
{
if(c < 32)return;
c -= 32;
u8* charData = (u8*)&font_bin[(CHAR_SIZE_X * CHAR_SIZE_Y * c) / 8];
u32* fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
int i, j;
for(i = 0; i < CHAR_SIZE_Y; i++)
{
u8 v= *(charData++);
for(j = 0; j < CHAR_SIZE_X; j++)
{
if(v & 1) *fb = 0x00000000;
else *fb = 0xFFFFFFFF;
v >>= 1;
fb++;
}
fb += FRAMEBUFFER_STRIDE_WORDS - CHAR_SIZE_X;
}
}
void drawString(char* str, int x, int y)
{
if(!str) return;
int k;
int dx = 0, dy = 0;
for(k = 0; str[k]; k++)
{
if(str[k] >= 32 && str[k] < 128) drawCharacter(str[k], x + dx, y + dy);
dx += 8;
if(str[k] == '\n')
{
dx = 0;
dy -= 8;
}
}
}
void _printf(int x, int y, const char *format, ...)
{
va_list args;
va_start(args, format);
char buffer[0x100];
FS_VSNPRINTF(buffer, sizeof(buffer), format, args);
drawString(buffer, x, y);
va_end(args);
}

View File

@ -1,11 +0,0 @@
#ifndef TEXT_H
#define TEXT_H
#include "types.h"
void clearScreen(u32 color);
void clearLine(int y, u32 color);
void drawString(char* str, int x, int y);
void _printf(int x, int y, const char *format, ...);
#endif

View File

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

View File

@ -1,31 +0,0 @@
/***************************************************************************
* 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_H_
#define __CONFIG_H_
#include "../../common/config_types.h"
extern cfw_config_t cfw_config;
#endif

View File

@ -21,7 +21,6 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include "config.h"
#include "utils.h" #include "utils.h"
#include "types.h" #include "types.h"
#include "elf_patcher.h" #include "elf_patcher.h"
@ -39,8 +38,7 @@ typedef struct
u32 cached; u32 cached;
} ios_map_shared_info_t; } ios_map_shared_info_t;
void instant_patches_setup(void) void instant_patches_setup(void){
{
// apply IOS ELF launch hook // apply IOS ELF launch hook
*(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios); *(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
@ -48,8 +46,6 @@ void instant_patches_setup(void)
*(volatile u32*)0x1070FAE8 = 0x05812070; *(volatile u32*)0x1070FAE8 = 0x05812070;
*(volatile u32*)0x1070FAEC = 0xEAFFFFF9; *(volatile u32*)0x1070FAEC = 0xEAFFFFF9;
if(cfw_config.noIosReload)
{
int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88; int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88;
// patch kernel dev node registration // patch kernel dev node registration
@ -79,8 +75,9 @@ void instant_patches_setup(void)
// set zero to start thread directly on first title change // set zero to start thread directly on first title change
*(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0; *(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0;
// down display launch image at this state
*(volatile u32*)(_text_start - 4 - 0x05100000 + 0x13D80000) = 0; *(volatile u32*)(0x050254D6 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x050254D6, MCP_LoadFile_patch);
*(volatile u32*)(0x05025242 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x05025242, MCP_ioctl100_patch);
ios_map_shared_info_t map_info; ios_map_shared_info_t map_info;
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000; map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
@ -99,4 +96,3 @@ void instant_patches_setup(void)
map_info.cached = 0xFFFFFFFF; map_info.cached = 0xFFFFFFFF;
_iosMapSharedUserExecution(&map_info); _iosMapSharedUserExecution(&map_info);
} }
}

View File

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

View File

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

View File

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

View File

@ -1,79 +0,0 @@
/***************************************************************************
* 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 "ios_bsp_patches.h"
#include "../../ios_bsp/ios_bsp_syms.h"
#include "fsa.h"
#include "utils.h"
#define BSP_PHYS_DIFF (-0xE6000000 + 0x13CC0000)
extern const patch_table_t fs_patches_table[];
extern const patch_table_t fs_patches_table_end[];
u32 bsp_get_phys_code_base(void)
{
return _text_start + BSP_PHYS_DIFF;
}
int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound)
{
void *tmpBuffer = (void*)0x00140000;
if(dumpFound)
{
int res = FSA_SDReadRawSectors(tmpBuffer, baseSector, 1);
if(res < 0)
return res;
}
else
{
//! just clear out the seeprom and it will be re-initialized on BSP module
//! TODO: maybe read in the seeprom here from SPI or BSP module
kernel_memset(tmpBuffer, 0, 0x200);
}
int level = disable_interrupts();
unsigned int control_register = disable_mmu();
kernel_memcpy((void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), tmpBuffer, 0x200);
restore_mmu(control_register);
enable_interrupts(level);
return 0;
}
void bsp_run_patches(u32 ios_elf_start)
{
section_write(ios_elf_start, _text_start, (void*)bsp_get_phys_code_base(), _text_end - _text_start);
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
section_write(ios_elf_start, _seeprom_buffer_start, (void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), 0x200);
section_write_word(ios_elf_start, 0xE600D08C, ARM_B(0xE600D08C, EEPROM_SPI_ReadWord));
section_write_word(ios_elf_start, 0xE600D010, ARM_B(0xE600D010, EEPROM_SPI_WriteWord));
section_write_word(ios_elf_start, 0xE600CF5C, ARM_B(0xE600CF5C, EEPROM_WriteControl));
}

View File

@ -1,31 +0,0 @@
/***************************************************************************
* 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 _BSP_PATCHES_H_
#define _BSP_PATCHES_H_
u32 bsp_get_phys_code_base(void);
void bsp_run_patches(u32 ios_elf_start);
int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound);
#endif

View File

@ -1,102 +0,0 @@
/***************************************************************************
* 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 "ios_fs_patches.h"
#include "config.h"
#include "../../ios_fs/ios_fs_syms.h"
#define FS_PHYS_DIFF 0
#define FS_SYSLOG_OUTPUT 0x107F0C84
#define FS_PRINTF_SYSLOG 0x107F5720
#define CALL_FS_REGISTERMDPHYSICALDEVICE 0x107BD81C
#define FS_GETMDDEVICEBYID 0x107187C4
#define FS_CREATEDEVTHREAD_HOOK 0x10700294
#define FS_USB_READ 0x1077F1C0
#define FS_USB_WRITE 0x1077F35C
#define FS_SLC_READ1 0x107B998C
#define FS_SLC_READ2 0x107B98FC
#define FS_SLC_WRITE1 0x107B9870
#define FS_SLC_WRITE2 0x107B97E4
#define FS_MLC_READ1 0x107DC760
#define FS_MLC_READ2 0x107DCDE4
#define FS_MLC_WRITE1 0x107DC0C0
#define FS_MLC_WRITE2 0x107DC73C
#define FS_SDCARD_READ1 0x107BDDD0
#define FS_SDCARD_WRITE1 0x107BDD60
extern const patch_table_t fs_patches_table[];
extern const patch_table_t fs_patches_table_end[];
u32 fs_get_phys_code_base(void)
{
return _text_start + FS_PHYS_DIFF;
}
void fs_run_patches(u32 ios_elf_start)
{
// write wupserver code and bss
section_write(ios_elf_start, _text_start, (void*)fs_get_phys_code_base(), _text_end - _text_start);
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
// patch FS logging
section_write_word(ios_elf_start, FS_PRINTF_SYSLOG, ARM_B(FS_PRINTF_SYSLOG, FS_SYSLOG_OUTPUT));
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_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, 0x1070F87C, ARM_BL(0x1070F87C, FSA_AttachVolume_FillDescription_hook));
//section_write_word(ios_elf_start, 0x10700EFC, ARM_BL(0x10700EFC, FSA_AsyncCommandCallback_hook));
// patch mounting FAT and allow all devices instead of only SD card
//section_write_word(ios_elf_start, 0x1078E074, 0xEA000002);
// patch FSA_MakeQuota to not store command -> command is modified depending on wether it is USB FAT or not
//section_write_word(ios_elf_start, 0x1070BE0C, 0xE1A00000);
//section_write_word(ios_elf_start, 0x1070BE00, ARM_BL(0x1070BE00, FSA_MakeQuota_asm_hook));
section_write_word(ios_elf_start, FS_CREATEDEVTHREAD_HOOK, ARM_B(FS_CREATEDEVTHREAD_HOOK, createDevThread_hook));
u32 patch_count = (u32)(((u8*)fs_patches_table_end) - ((u8*)fs_patches_table)) / sizeof(patch_table_t);
patch_table_entries(ios_elf_start, fs_patches_table, patch_count);
//section_write_word(ios_elf_start, 0x10701F6C, ARM_BL(0x10701F6C, FSMakeQuota));
//section_write_word(ios_elf_start, 0x10702764, ARM_BL(0x10702764, FSCreateDir));
//section_write_word(ios_elf_start, 0x1070278C, ARM_BL(0x1070278C, FSChangeDir));
//section_write_word(ios_elf_start, 0x107024B4, ARM_BL(0x107024B4, FSOpenFile));
//section_write_word(ios_elf_start, 0x10703F4C, ARM_BL(0x10703F4C, FSWriteFileIssueCommand));
}

View File

@ -1,30 +0,0 @@
/***************************************************************************
* 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 _FS_PATCHES_H_
#define _FS_PATCHES_H_
u32 fs_get_phys_code_base(void);
void fs_run_patches(u32 ios_elf_start);
#endif

View File

@ -1,40 +0,0 @@
.arm
# patch out sdcard deinitialization
patch_mdExit:
bx lr
# patch out FSRawOpen access
patch_FSRawOpen:
streq r2, [r1, #0x70]
.word 0xEAFFFFF9
# nop out hmac memcmp
patch_hmac_check:
mov r0, #0
# null out references to slcSomething1 and slcSomething2
# (nulling them out is apparently ok; more importantly, i'm not sure what they do and would rather get a crash than unwanted slc-writing)
slcSomething1:
.word 0x00000000
slcSomething2:
.word 0x00000000
#syslogOutput_hook:
# push {r0,lr}
# bl dump_syslog
# pop {r0,lr}
# restore original instruction
# pop {r4-r8,r10,pc}
.globl fs_patches_table, fs_patches_table_end
fs_patches_table:
# origin data size
.word 0x107BD374, patch_mdExit, 4
.word 0x1070FAE8, patch_FSRawOpen, 8
.word 0x107B96B8, slcSomething1, 8
.word 0x107206F0, patch_hmac_check, 4
# .word 0x107F0B68, syslogOutput_hook, 4
fs_patches_table_end:

View File

@ -23,7 +23,6 @@
***************************************************************************/ ***************************************************************************/
#include "types.h" #include "types.h"
#include "elf_patcher.h" #include "elf_patcher.h"
#include "config.h"
#include "ios_mcp_patches.h" #include "ios_mcp_patches.h"
#include "../../ios_mcp/ios_mcp.bin.h" #include "../../ios_mcp/ios_mcp.bin.h"
#include "../../ios_mcp/ios_mcp_syms.h" #include "../../ios_mcp/ios_mcp_syms.h"
@ -46,11 +45,7 @@ void mcp_run_patches(u32 ios_elf_start)
section_write_word(ios_elf_start, 0x05056718, ARM_BL(0x05056718, _text_start)); section_write_word(ios_elf_start, 0x05056718, ARM_BL(0x05056718, _text_start));
if(cfw_config.syshaxXml) section_write_word(ios_elf_start, 0x05002BBE, THUMB_BL(0x05002BBE, patch_SD_access_check));
{
section_write(ios_elf_start, 0x050600DC, "/vol/system/config/syshax.xml", 0x20);
section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24);
}
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);

View File

@ -25,13 +25,9 @@
#include "../../common/kernel_commands.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_bsp_patches.h"
#include "kernel_patches.h" #include "kernel_patches.h"
#include "exception_handler.h" #include "exception_handler.h"
#include "fsa.h" #include "fsa.h"
#include "config.h"
#include "utils.h" #include "utils.h"
extern void __KERNEL_CODE_START(void); extern void __KERNEL_CODE_START(void);
@ -40,8 +36,6 @@ extern void __KERNEL_CODE_END(void);
extern const patch_table_t kernel_patches_table[]; extern const patch_table_t kernel_patches_table[];
extern const patch_table_t kernel_patches_table_end[]; extern const patch_table_t kernel_patches_table_end[];
static u8 otp_buffer[0x400];
static const u32 mcpIoMappings_patch[] = static const u32 mcpIoMappings_patch[] =
{ {
// vaddr paddr size ? ? ? // vaddr paddr size ? ? ?
@ -76,44 +70,12 @@ static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3)
kernel_memcpy((void*)arg1, (void*) arg2, arg3); kernel_memcpy((void*)arg1, (void*) arg2, arg3);
break; break;
} }
case KERNEL_GET_CFW_CONFIG:
{
//set_domain_register(0xFFFFFFFF);
kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
break;
}
default: default:
return -1; return -1;
} }
return 0; return 0;
} }
static int kernel_read_otp_internal(int index, void* out_buf, u32 size)
{
kernel_memcpy(out_buf, otp_buffer + (index << 2), size);
return 0;
}
int kernel_init_otp_buffer(u32 sd_sector, int dumpFound)
{
int res;
if(dumpFound)
{
res = FSA_SDReadRawSectors(otp_buffer, sd_sector, 2);
}
else
{
int (*orig_kernel_read_otp_internal)(int index, void* out_buf, u32 size) = (void*)0x08120248;
res = orig_kernel_read_otp_internal(0, otp_buffer, 0x400);
}
if((res == 0) && (dumpFound == 0))
{
FSA_SDWriteRawSectors(otp_buffer, sd_sector, 2);
}
return res;
}
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H) void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
{ {
@ -129,11 +91,6 @@ 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 && cfw_config.seeprom_red)
bsp_run_patches(ios_elf_start);
restore_mmu(control_register); restore_mmu(control_register);
enable_interrupts(level); enable_interrupts(level);
@ -155,12 +112,6 @@ void kernel_run_patches(u32 ios_elf_start)
section_write_word(ios_elf_start, 0x0812CD2C, ARM_B(0x0812CD2C, kernel_syscall_0x81)); section_write_word(ios_elf_start, 0x0812CD2C, ARM_B(0x0812CD2C, kernel_syscall_0x81));
if(cfw_config.redNAND && cfw_config.otp_red)
{
section_write(ios_elf_start, (u32)otp_buffer, otp_buffer, 0x400);
section_write_word(ios_elf_start, 0x08120248, ARM_B(0x08120248, kernel_read_otp_internal));
}
u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t); u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t);
patch_table_entries(ios_elf_start, kernel_patches_table, patch_count); patch_table_entries(ios_elf_start, kernel_patches_table, patch_count);
} }

View File

@ -22,19 +22,11 @@
* distribution. * distribution.
***************************************************************************/ ***************************************************************************/
#include "types.h" #include "types.h"
#include "config.h"
#include "utils.h" #include "utils.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_bsp_patches.h"
#include "instant_patches.h" #include "instant_patches.h"
#define USB_PHYS_CODE_BASE 0x101312D0 #define USB_PHYS_CODE_BASE 0x101312D0
cfw_config_t cfw_config;
typedef struct typedef struct
{ {
u32 size; u32 size;
@ -94,31 +86,12 @@ int _main()
payload_info_t *payloads = (payload_info_t*)0x00148000; payload_info_t *payloads = (payload_info_t*)0x00148000;
kernel_memcpy((void*)&cfw_config, payloads->data, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
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) );
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.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); 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) );
if(cfw_config.launchImage)
{
kernel_memcpy((void*)MCP_LAUNCH_IMG_PHYS_ADDR, payloads->data, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
}
// run all instant patches as necessary // run all instant patches as necessary
instant_patches_setup(); instant_patches_setup();
@ -132,10 +105,5 @@ int _main()
enable_interrupts(level); enable_interrupts(level);
if(cfw_config.redNAND)
{
redirection_setup();
}
return 0; return 0;
} }

View File

@ -1,92 +0,0 @@
/***************************************************************************
* 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 "config.h"
#include "utils.h"
#include "fsa.h"
#include "kernel_patches.h"
#include "ios_bsp_patches.h"
void redirection_setup(void)
{
int seepromDumpFound = 0;
u32 seepromDumpBaseSector = 0x4FF;
int otpDumpFound = 0;
u32 otpDumpBaseSector = 0x4FD;
int writeInfoSector = 0;
sdio_nand_signature_sector_t *infoSector = (sdio_nand_signature_sector_t*)0x00141000;
kernel_memset(infoSector, 0x00, 0x200);
int result = FSA_SDReadRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1);
if(result < 0)
return;
if(infoSector->signature == NAND_DUMP_SIGNATURE)
{
int i;
for(i = 0; i < NAND_MAX_DESC_TYPES; i++)
{
if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_SEEPROM)
{
seepromDumpFound = 1;
seepromDumpBaseSector = infoSector->nand_descriptions[i].base_sector;
}
if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_OTP)
{
otpDumpFound = 1;
otpDumpBaseSector = infoSector->nand_descriptions[i].base_sector;
}
}
}
if(cfw_config.seeprom_red)
{
bsp_init_seeprom_buffer(seepromDumpBaseSector, seepromDumpFound);
if(seepromDumpFound == 0)
{
infoSector->nand_descriptions[3].nand_type = NAND_DESC_TYPE_SEEPROM;
infoSector->nand_descriptions[3].base_sector = seepromDumpBaseSector;
infoSector->nand_descriptions[3].sector_count = 1;
writeInfoSector++;
}
}
if(cfw_config.otp_red)
{
kernel_init_otp_buffer(otpDumpBaseSector, otpDumpFound);
if(otpDumpFound == 0)
{
infoSector->nand_descriptions[4].nand_type = NAND_DESC_TYPE_OTP;
infoSector->nand_descriptions[4].base_sector = otpDumpBaseSector;
infoSector->nand_descriptions[4].sector_count = 2;
writeInfoSector++;
}
}
if(writeInfoSector > 0)
{
FSA_SDWriteRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1);
}
}

View File

@ -1,29 +0,0 @@
/***************************************************************************
* 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 _REDIRECTION_SETUP_H_
#define _REDIRECTION_SETUP_H_
void redirection_setup(void);
#endif

View File

@ -6,6 +6,8 @@ ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
export PATH:=$(DEVKITARM)/bin:$(PATH) export PATH:=$(DEVKITARM)/bin:$(PATH)
endif endif
LOG_IP = 0xc0a800ea
ifneq ($(LOG_IP),) ifneq ($(LOG_IP),)
CFLAGS += -DLOG_IP=$(LOG_IP) CFLAGS += -DLOG_IP=$(LOG_IP)
endif endif

View File

@ -8,11 +8,11 @@
#ifdef LOG_IP #ifdef LOG_IP
static int log_socket = 0; static int log_socket = 0;
int log_init(unsigned int ipAddress) int log_init(unsigned int ipAddress){
{
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0) if (log_socket < 0){
return log_socket; return log_socket;
}
struct sockaddr_in connect_addr; struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr)); memset(&connect_addr, 0, sizeof(connect_addr));
@ -40,6 +40,9 @@ void log_deinit()
static void log_print(const char *str, int len) static void log_print(const char *str, int len)
{ {
if(log_socket < 0) {
return;
}
int ret; int ret;
while (len > 0) { while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet

View File

@ -5,7 +5,6 @@
#include "ipc.h" #include "ipc.h"
#include "svc.h" #include "svc.h"
#include "text.h" #include "text.h"
#include "../../common/config_types.h"
#include "../../common/kernel_commands.h" #include "../../common/kernel_commands.h"
static int threadsStarted = 0; static int threadsStarted = 0;
@ -15,17 +14,23 @@ 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);
if(cfw_config.launchImage)
{
drawSplashScreen();
}
wupserver_init(); wupserver_init();
ipc_init(); ipc_init();
} }
return 0; return 0;
} }
void patch_SD_access_check(void) {
__asm__ volatile(
".thumb\n"
//clobbered instructions
"add r0, r7, r2\n"
//app.permissions.r2.mask seems to be 0xFFFFFFFFFFFFFFFF for every application
"ldr r1, =0x32\n"
"sub r3, r3, #7\n"
"strb r1, [r3]\n"
//this instruction was also clobbered but we use r1 so we do it after our patch stuff
"movs r1, #0\n"
"bx lr");
}

View File

@ -18,6 +18,8 @@
#include "logger.h" #include "logger.h"
#include "ipc_types.h" #include "ipc_types.h"
#include "fsa.h"
#include "svc.h"
#include <string.h> #include <string.h>
typedef enum { typedef enum {
@ -53,7 +55,7 @@ int (*const MCP_DoLoadFile)(const char* path, const char* path2, void* outputBuf
int (*const MCP_UnknownStuff)(const char* path, u32 pos, void* outputBuffer, u32 outLength, u32 outLength2, u32 unk) = (void*)0x05014CAC + 1; int (*const MCP_UnknownStuff)(const char* path, u32 pos, void* outputBuffer, u32 outLength, u32 outLength2, u32 unk) = (void*)0x05014CAC + 1;
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request); static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request);
static bool replacerpx = false; static bool skipPPCSetup = false;
static bool didrpxfirstchunk = false; static bool didrpxfirstchunk = false;
static char rpxpath[0x280]; static char rpxpath[0x280];
@ -74,11 +76,11 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
log("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io); log("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
log("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name); log("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
if (request->type == LOAD_FILE_CAFE_OS && /*if (request->type == LOAD_FILE_CAFE_OS &&
request->name[0] == '*') { request->name[0] == '*') {
char path[0x40]; char path[0x40];
/* Translate request->name to a path by replacing * with / */ // Translate request->name to a path by replacing * with /
for (int i = 0; i < 0x40; ++i) { for (int i = 0; i < 0x40; ++i) {
if (request->name[i] == '*') { if (request->name[i] == '*') {
path[i] = '/'; path[i] = '/';
@ -89,35 +91,82 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
int result = MCP_LoadCustomFile(path, msg, request); int result = MCP_LoadCustomFile(path, msg, request);
if (result >= 0) return result; if (result >= 0) return result;
} else if (replacerpx) { }*/
/* RPX replacement! /* RPX replacement!
Only replace this chunk if:
- replacerpx is true (replace the next rpx to be loaded)
- this file is an rpx
and either of the following:
- we haven't read the first chunk yet
- this is not the first chunk
The goal here is only to replace an rpx once. Reading at pos = 0 signifies a The goal here is only to replace an rpx once. Reading at pos = 0 signifies a
new rpx load - these conditions detect that. */ new rpx load - these conditions detect that. */
char* extension = request->name + strlen(request->name) - 3;
if (extension[0] == 'r' &&
extension[1] == 'p' &&
extension[2] == 'x') {
if (request->name[0] == 'm' &&
request->name[1] == 'e' &&
request->name[2] == 'n' &&
request->name[3] == '.' &&
request->name[4] == 'r' &&
request->name[5] == 'p' &&
request->name[6] == 'x'
&& rpxpath[0] != 'd'
&& !skipPPCSetup){
int fsa_h = svcOpen("/dev/fsa", 0);
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
svcClose(fsa_h);
char * f_path = "/vol/storage_iosu_homebrew/wiiu/payload.rpx";;
int result = MCP_LoadCustomFile(f_path, msg, request);
if (result >= 0) {
return result;
}
}else if (request->name[0] == 's' &&
request->name[1] == 'a' &&
request->name[2] == 'f' &&
request->name[3] == 'e' &&
request->name[4] == '.' &&
request->name[5] == 'r' &&
request->name[6] == 'p' &&
request->name[7] == 'x'){
char * final_path = rpxpath;
if(rpxpath[0] == '\0') {
final_path = "/vol/storage_iosu_homebrew/wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
if (request->pos == 0){
didrpxfirstchunk = false;
}
}
char* extension = request->name + strlen(request->name) - 4;
if( extension[0] == '.' &&
extension[1] == 'r' &&
extension[2] == 'p' &&
extension[3] == 'x') {
if(final_path != NULL){
if (!didrpxfirstchunk || request->pos > 0) { if (!didrpxfirstchunk || request->pos > 0) {
int result = MCP_LoadCustomFile(rpxpath, msg, request); int fsa_h = svcOpen("/dev/fsa", 0);
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
svcClose(fsa_h);
int result = MCP_LoadCustomFile(final_path, msg, request);
rpxpath[0] = '\0';
if (result >= 0) { if (result >= 0) {
if (request->pos == 0) didrpxfirstchunk = true; if (request->pos == 0) didrpxfirstchunk = true;
return result; return result;
} }
} else {
/* This is the second time reading the first chunk of an rpx.
Therefore we have already replaced the rpx we were asked to. */
replacerpx = false;
} }
} }
} }
}
if (rpxpath[0] == 'd' &&
rpxpath[1] == 'o' &&
rpxpath[2] == 'n' &&
rpxpath[3] == 'e'){
skipPPCSetup = true;
rpxpath[0] = '\0';
}
return real_MCP_LoadFile(msg); return real_MCP_LoadFile(msg);
} }
@ -125,10 +174,18 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request) { static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request) {
log("Load custom path \"%s\"\n", path); log("Load custom path \"%s\"\n", path);
int filesize = 0;
int fileoffset = 0;
if(filesize > 0 && (request->pos + fileoffset > filesize)){
return 0;
}
/* TODO: If this fails, try last argument as 1 */ /* TODO: If this fails, try last argument as 1 */
int bytesRead = 0; int bytesRead = 0;
int result = MCP_DoLoadFile(path, NULL, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos, &bytesRead, 0); int result = MCP_DoLoadFile(path, NULL, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos + fileoffset, &bytesRead, 0);
log("MCP_DoLoadFile returned %d, bytesRead = %d\n", result, bytesRead); log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, request->pos + fileoffset);
if (result >= 0) { if (result >= 0) {
if (!bytesRead) { if (!bytesRead) {
@ -136,10 +193,13 @@ static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* r
} }
/* TODO: If this fails, try last argument as 1 */ /* TODO: If this fails, try last argument as 1 */
result = MCP_UnknownStuff(path, request->pos, msg->ioctl.buffer_io, msg->ioctl.length_io, msg->ioctl.length_io, 0); result = MCP_UnknownStuff(path, request->pos + fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, msg->ioctl.length_io, 0);
log("MCP_UnknownStuff returned %d\n", result); log("MCP_UnknownStuff returned %d\n", result);
if (result >= 0) { if (result >= 0) {
if(filesize > 0 && (bytesRead + request->pos > filesize)){
return filesize - request->pos;
}
return bytesRead; return bytesRead;
} }
} }
@ -158,10 +218,10 @@ int _MCP_ioctl100_patch(ipcmessage* msg) {
FAIL_ON(!msg->ioctl.length_in, 0); FAIL_ON(!msg->ioctl.length_in, 0);
FAIL_ON(msg->ioctl.length_in > sizeof(rpxpath) - 1, msg->ioctl.length_in); FAIL_ON(msg->ioctl.length_in > sizeof(rpxpath) - 1, msg->ioctl.length_in);
strncpy(rpxpath, (const char*)msg->ioctl.buffer_in, sizeof(rpxpath) - 1); memset(rpxpath,0,sizeof(rpxpath));
rpxpath[sizeof(rpxpath) - 1] = '\0'; strncpy(rpxpath, (const char*)msg->ioctl.buffer_in, msg->ioctl.length_in);
//rpxpath[strlen(rpxpath)] = '\0';
replacerpx = true;
didrpxfirstchunk = false; didrpxfirstchunk = false;
log("Will load %s for next title\n", rpxpath); log("Will load %s for next title\n", rpxpath);

Binary file not shown.

Binary file not shown.

325
mocha.cbp
View File

@ -1,325 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="mocha" />
<Option makefile_is_custom="1" />
<Option pch_mode="2" />
<Option compiler="ppc-gcc" />
<Build>
<Target title="build">
<Option output="bin/Release/mocha" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="ppc-gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<MakeCommands>
<Build command="make" />
<CompileFile command="$make -f $makefile $file" />
<Clean command="$make -f $makefile clean$target" />
<DistClean command="$make -f $makefile distclean$target" />
<AskRebuildNeeded command="$make -q -f $makefile $target" />
<SilentBuild command="make &gt; $(CMD_NULL)" />
</MakeCommands>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="build/cfw_config.d" />
<Unit filename="build/entry.d" />
<Unit filename="build/exception_handler.d" />
<Unit filename="build/fs_functions.d" />
<Unit filename="build/fs_utils.d" />
<Unit filename="build/gx2_functions.d" />
<Unit filename="build/ios_exploit.d" />
<Unit filename="build/logger.d" />
<Unit filename="build/main.d" />
<Unit filename="build/memory.d" />
<Unit filename="build/menu.d" />
<Unit filename="build/os_functions.d" />
<Unit filename="build/sd_fat_devoptab.d" />
<Unit filename="build/socket_functions.d" />
<Unit filename="build/sys_functions.d" />
<Unit filename="build/vpad_functions.d" />
<Unit filename="ios_bsp/build/fsa.d" />
<Unit filename="ios_bsp/build/seeprom.d" />
<Unit filename="ios_bsp/build/seeprom_asm.d" />
<Unit filename="ios_bsp/build/svc.d" />
<Unit filename="ios_bsp/ios_bsp.bin.h" />
<Unit filename="ios_bsp/ios_bsp_syms.h" />
<Unit filename="ios_bsp/source/fsa.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_bsp/source/fsa.h" />
<Unit filename="ios_bsp/source/seeprom.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_bsp/source/seeprom_asm.s" />
<Unit filename="ios_bsp/source/svc.h" />
<Unit filename="ios_bsp/source/svc.s" />
<Unit filename="ios_bsp/source/types.h" />
<Unit filename="ios_fs/build/devices.d" />
<Unit filename="ios_fs/build/dumper.d" />
<Unit filename="ios_fs/build/fat32_format.d" />
<Unit filename="ios_fs/build/font.d" />
<Unit filename="ios_fs/build/function_hooks.d" />
<Unit filename="ios_fs/build/main.d" />
<Unit filename="ios_fs/build/mlcio.d" />
<Unit filename="ios_fs/build/sdio.d" />
<Unit filename="ios_fs/build/svc.d" />
<Unit filename="ios_fs/build/text.d" />
<Unit filename="ios_fs/ios_fs.bin.h" />
<Unit filename="ios_fs/ios_fs_syms.h" />
<Unit filename="ios_fs/source/devices.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/devices.h" />
<Unit filename="ios_fs/source/dumper.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/dumper.h" />
<Unit filename="ios_fs/source/fat32_format.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/fat32_format.h" />
<Unit filename="ios_fs/source/font.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/font_bin.h" />
<Unit filename="ios_fs/source/function_hooks.s" />
<Unit filename="ios_fs/source/hardware_registers.h" />
<Unit filename="ios_fs/source/imports.h" />
<Unit filename="ios_fs/source/main.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/mlcio.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/mlcio.h" />
<Unit filename="ios_fs/source/sdio.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/sdio.h" />
<Unit filename="ios_fs/source/svc.h" />
<Unit filename="ios_fs/source/svc.s" />
<Unit filename="ios_fs/source/text.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_fs/source/text.h" />
<Unit filename="ios_fs/source/types.h" />
<Unit filename="ios_kernel/build/crt0.d" />
<Unit filename="ios_kernel/build/elf_patcher.d" />
<Unit filename="ios_kernel/build/exception_handler.d" />
<Unit filename="ios_kernel/build/fsa.d" />
<Unit filename="ios_kernel/build/instant_patches.d" />
<Unit filename="ios_kernel/build/ios_bsp_patches.d" />
<Unit filename="ios_kernel/build/ios_fs_patches.d" />
<Unit filename="ios_kernel/build/ios_fs_patches_asm.d" />
<Unit filename="ios_kernel/build/ios_mcp_patches.d" />
<Unit filename="ios_kernel/build/ios_mcp_patches_asm.d" />
<Unit filename="ios_kernel/build/kernel_patches.d" />
<Unit filename="ios_kernel/build/kernel_patches_asm.d" />
<Unit filename="ios_kernel/build/main.d" />
<Unit filename="ios_kernel/build/redirection_setup.d" />
<Unit filename="ios_kernel/build/text.d" />
<Unit filename="ios_kernel/build/utils.d" />
<Unit filename="ios_kernel/ios_kernel.bin.h" />
<Unit filename="ios_kernel/ios_kernel_syms.h" />
<Unit filename="ios_kernel/source/config.h" />
<Unit filename="ios_kernel/source/crt0.s" />
<Unit filename="ios_kernel/source/elf_abi.h" />
<Unit filename="ios_kernel/source/elf_patcher.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/elf_patcher.h" />
<Unit filename="ios_kernel/source/exception_handler.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/exception_handler.h" />
<Unit filename="ios_kernel/source/font_bin.h" />
<Unit filename="ios_kernel/source/fsa.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/fsa.h" />
<Unit filename="ios_kernel/source/instant_patches.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/instant_patches.h" />
<Unit filename="ios_kernel/source/ios_bsp_patches.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/ios_bsp_patches.h" />
<Unit filename="ios_kernel/source/ios_fs_patches.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/ios_fs_patches.h" />
<Unit filename="ios_kernel/source/ios_fs_patches_asm.s" />
<Unit filename="ios_kernel/source/ios_mcp_patches.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/ios_mcp_patches.h" />
<Unit filename="ios_kernel/source/ios_mcp_patches_asm.s" />
<Unit filename="ios_kernel/source/kernel_patches.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/kernel_patches.h" />
<Unit filename="ios_kernel/source/kernel_patches_asm.s" />
<Unit filename="ios_kernel/source/main.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/redirection_setup.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/redirection_setup.h" />
<Unit filename="ios_kernel/source/text.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/text.h" />
<Unit filename="ios_kernel/source/types.h" />
<Unit filename="ios_kernel/source/utils.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_kernel/source/utils.h" />
<Unit filename="ios_mcp/build/crt0.d" />
<Unit filename="ios_mcp/build/font.d" />
<Unit filename="ios_mcp/build/fsa.d" />
<Unit filename="ios_mcp/build/imports.d" />
<Unit filename="ios_mcp/build/ipc.d" />
<Unit filename="ios_mcp/build/logger.d" />
<Unit filename="ios_mcp/build/main.d" />
<Unit filename="ios_mcp/build/net_ifmgr_ncl.d" />
<Unit filename="ios_mcp/build/socket.d" />
<Unit filename="ios_mcp/build/svc.d" />
<Unit filename="ios_mcp/build/text.d" />
<Unit filename="ios_mcp/ios_mcp.bin.h" />
<Unit filename="ios_mcp/ios_mcp_syms.h" />
<Unit filename="ios_mcp/source/crt0.s" />
<Unit filename="ios_mcp/source/font.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/font_bin.h" />
<Unit filename="ios_mcp/source/fsa.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/fsa.h" />
<Unit filename="ios_mcp/source/imports.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/imports.h" />
<Unit filename="ios_mcp/source/ipc.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/ipc.h" />
<Unit filename="ios_mcp/source/ipc_types.h" />
<Unit filename="ios_mcp/source/logger.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/logger.h" />
<Unit filename="ios_mcp/source/main.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/net_ifmgr_ncl.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/net_ifmgr_ncl.h" />
<Unit filename="ios_mcp/source/socket.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/socket.h" />
<Unit filename="ios_mcp/source/svc.h" />
<Unit filename="ios_mcp/source/svc.s" />
<Unit filename="ios_mcp/source/text.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="ios_mcp/source/text.h" />
<Unit filename="ios_mcp/source/types.h" />
<Unit filename="ios_usb/build/crt0.d" />
<Unit filename="ios_usb/build/main.d" />
<Unit filename="ios_usb/ios_usb.bin.h" />
<Unit filename="ios_usb/ios_usb_syms.h" />
<Unit filename="ios_usb/source/crt0.s" />
<Unit filename="ios_usb/source/main.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/cfw_config.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/cfw_config.h" />
<Unit filename="src/common/common.h" />
<Unit filename="src/common/fs_defs.h" />
<Unit filename="src/common/os_defs.h" />
<Unit filename="src/common/types.h" />
<Unit filename="src/dynamic_libs/fs_defs.h" />
<Unit filename="src/dynamic_libs/fs_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/fs_functions.h" />
<Unit filename="src/dynamic_libs/gx2_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/gx2_functions.h" />
<Unit filename="src/dynamic_libs/gx2_types.h" />
<Unit filename="src/dynamic_libs/os_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/os_functions.h" />
<Unit filename="src/dynamic_libs/os_types.h" />
<Unit filename="src/dynamic_libs/socket_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/socket_functions.h" />
<Unit filename="src/dynamic_libs/sys_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/sys_functions.h" />
<Unit filename="src/dynamic_libs/vpad_functions.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/dynamic_libs/vpad_functions.h" />
<Unit filename="src/entry.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/fs/fs_utils.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/fs/fs_utils.h" />
<Unit filename="src/fs/sd_fat_devoptab.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/fs/sd_fat_devoptab.h" />
<Unit filename="src/ios_exploit.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/ios_exploit.h" />
<Unit filename="src/main.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/main.h" />
<Unit filename="src/menu.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/menu.h" />
<Unit filename="src/system/exception_handler.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/system/exception_handler.h" />
<Unit filename="src/system/memory.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/system/memory.h" />
<Unit filename="src/utils/logger.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/utils/logger.h" />
<Unit filename="src/utils/utils.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -1,152 +0,0 @@
/***************************************************************************
* 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 <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <stdio.h>
#include "cfw_config.h"
#include "fs/fs_utils.h"
static int split_string(const char *string, char splitChar, char *left, char *right, int size)
{
int cnt = 0;
char *writePtr = left;
while(*string != '\0' && *string != '\n' && *string != '\r' && *string != splitChar && (cnt+1) < size)
{
*writePtr++ = *string++;
cnt++;
}
*writePtr = 0;
*right = 0;
writePtr--;
// remove trailing spaces
while(writePtr > left && *writePtr == ' ')
*writePtr-- = 0;
if(*string == splitChar)
{
string++;
writePtr = right;
// skip spaces after split character
while(*string == ' ')
string++;
cnt = 0;
while(*string != '\0' && *string != '\n' && *string != '\r' && (cnt+1) < size)
{
*writePtr++ = *string++;
}
*writePtr = 0;
return 1;
}
else
{
return -1;
}
}
void default_config(cfw_config_t * config)
{
memset(config, 0, sizeof(cfw_config_t));
config->viewMode = 0;
config->directLaunch = 0;
config->launchImage = 1;
config->noIosReload = 0;
config->launchSysMenu = 1;
config->redNAND = 0;
config->seeprom_red = 0;
config->otp_red = 0;
config->syshaxXml = 0;
}
int read_config(cfw_config_t * config)
{
FILE *pFile = fopen(CONFIG_PATH, "rb");
if(!pFile)
return -1;
char option[64];
char value[64];
char line[0x100];
while(fgets(line, sizeof(line), pFile) != 0)
{
if(line[0] == '#' || line[0] == '[')
continue;
if(split_string(line, '=', option, value, sizeof(option)) == 1)
{
if(strcmp(option, "directLaunch") == 0)
config->directLaunch = atoi(value);
else if(strcmp(option, "launchImage") == 0)
config->launchImage = atoi(value);
else if(strcmp(option, "redNAND") == 0)
config->redNAND = atoi(value);
else if(strcmp(option, "seeprom_red") == 0)
config->seeprom_red = atoi(value);
else if(strcmp(option, "otp_red") == 0)
config->otp_red = atoi(value);
else if(strcmp(option, "syshaxXml") == 0)
config->syshaxXml = atoi(value);
else if(strcmp(option, "viewMode") == 0)
config->viewMode = atoi(value);
else if(strcmp(option, "noIosReload") == 0)
config->noIosReload = atoi(value);
else if(strcmp(option, "launchSysMenu") == 0)
config->launchSysMenu = atoi(value);
}
}
fclose(pFile);
return 0;
}
int write_config(cfw_config_t * config)
{
CreateSubfolder(APP_PATH);
FILE *pFile = fopen(CONFIG_PATH, "wb");
if(!pFile)
return -1;
fprintf(pFile, "[MOCHA]\n");
fprintf(pFile, "viewMode=%i\n", config->viewMode);
fprintf(pFile, "directLaunch=%i\n", config->directLaunch);
fprintf(pFile, "launchImage=%i\n", config->launchImage);
fprintf(pFile, "noIosReload=%i\n", config->noIosReload);
fprintf(pFile, "launchSysMenu=%i\n", config->launchSysMenu);
fprintf(pFile, "redNAND=%i\n", config->redNAND);
fprintf(pFile, "seeprom_red=%i\n", config->seeprom_red);
fprintf(pFile, "otp_red=%i\n", config->otp_red);
fprintf(pFile, "syshaxXml=%i\n", config->syshaxXml);
fclose(pFile);
return 0;
}

View File

@ -1,37 +0,0 @@
/***************************************************************************
* 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 CFW_CONFIG_H_
#define CFW_CONFIG_H_
#define APP_VERSION "v0.2"
#define APP_PATH "sd:/wiiu/apps/mocha"
#define CONFIG_PATH (APP_PATH "/config.ini")
#include "../common/config_types.h"
void default_config(cfw_config_t * config);
int read_config(cfw_config_t * config);
int write_config(cfw_config_t * config);
#endif

View File

@ -1,36 +0,0 @@
#ifndef COMMON_H
#define COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include "os_defs.h"
#define CAFE_OS_SD_PATH "/vol/external01"
#define SD_PATH "sd:"
#define WIIU_PATH "/wiiu"
#ifndef MEM_BASE
#define MEM_BASE (0x00800000)
#endif
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#define EXIT_HBL_EXIT 0xFFFFFFFE
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
#ifdef __cplusplus
}
#endif
#endif /* COMMON_H */

View File

@ -1,62 +0,0 @@
#ifndef FS_DEFS_H
#define FS_DEFS_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* FS defines and types */
#define FS_MAX_LOCALPATH_SIZE 511
#define FS_MAX_MOUNTPATH_SIZE 128
#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE)
#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE
#define FS_STATUS_OK 0
#define FS_RET_UNSUPPORTED_CMD 0x0400
#define FS_RET_NO_ERROR 0x0000
#define FS_RET_ALL_ERROR (unsigned int)(-1)
#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000
/* max length of file/dir name */
#define FS_MAX_ENTNAME_SIZE 256
#define FS_SOURCETYPE_EXTERNAL 0
#define FS_SOURCETYPE_HFIO 1
#define FS_SOURCETYPE_HFIO 1
#define FS_MOUNT_SOURCE_SIZE 0x300
#define FS_CLIENT_SIZE 0x1700
#define FS_CMD_BLOCK_SIZE 0xA80
typedef struct
{
uint32_t flag;
uint32_t permission;
uint32_t owner_id;
uint32_t group_id;
uint32_t size;
uint32_t alloc_size;
uint64_t quota_size;
uint32_t ent_id;
uint64_t ctime;
uint64_t mtime;
uint8_t attributes[48];
} __attribute__((packed)) FSStat;
typedef struct
{
FSStat stat;
char name[FS_MAX_ENTNAME_SIZE];
} FSDirEntry;
#ifdef __cplusplus
}
#endif
#endif /* FS_DEFS_H */

View File

@ -1,25 +0,0 @@
#ifndef __OS_DEFS_H_
#define __OS_DEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _OsSpecifics
{
unsigned int addr_OSDynLoad_Acquire;
unsigned int addr_OSDynLoad_FindExport;
unsigned int addr_OSTitle_main_entry;
unsigned int addr_KernSyscallTbl1;
unsigned int addr_KernSyscallTbl2;
unsigned int addr_KernSyscallTbl3;
unsigned int addr_KernSyscallTbl4;
unsigned int addr_KernSyscallTbl5;
} OsSpecifics;
#ifdef __cplusplus
}
#endif
#endif // __OS_DEFS_H_

View File

@ -1,7 +0,0 @@
#ifndef TYPES_H
#define TYPES_H
#include "dynamic_libs/os_types.h"
#endif /* TYPES_H */

View File

@ -1,14 +0,0 @@
#include <string.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/sys_functions.h"
#include "common/common.h"
#include "utils/utils.h"
#include "main.h"
int __entry_menu(int argc, char **argv)
{
//! *******************************************************************
//! * Jump to our application *
//! *******************************************************************
return Menu_Main();
}

View File

@ -1,184 +0,0 @@
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "common/fs_defs.h"
#include "dynamic_libs/fs_functions.h"
int MountFS(void *pClient, void *pCmd, char **mount_path)
{
int result = -1;
void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE);
if(!mountSrc)
return -3;
char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE);
if(!mountPath) {
free(mountSrc);
return -4;
}
memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE);
memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE);
// Mount sdcard
if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0)
{
result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
if((result == 0) && mount_path) {
*mount_path = (char*)malloc(strlen(mountPath) + 1);
if(*mount_path)
strcpy(*mount_path, mountPath);
}
}
free(mountPath);
free(mountSrc);
return result;
}
int UmountFS(void *pClient, void *pCmd, const char *mountPath)
{
int result = -1;
result = FSUnmount(pClient, pCmd, mountPath, -1);
return result;
}
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
{
//! always initialze input
*inbuffer = NULL;
if(size)
*size = 0;
int iFd = open(filepath, O_RDONLY);
if (iFd < 0)
return -1;
u32 filesize = lseek(iFd, 0, SEEK_END);
lseek(iFd, 0, SEEK_SET);
u8 *buffer = (u8 *) malloc(filesize);
if (buffer == NULL)
{
close(iFd);
return -2;
}
u32 blocksize = 0x4000;
u32 done = 0;
int readBytes = 0;
while(done < filesize)
{
if(done + blocksize > filesize) {
blocksize = filesize - done;
}
readBytes = read(iFd, buffer + done, blocksize);
if(readBytes <= 0)
break;
done += readBytes;
}
close(iFd);
if (done != filesize)
{
free(buffer);
return -3;
}
*inbuffer = buffer;
//! sign is optional input
if(size)
{
*size = filesize;
}
return filesize;
}
int CheckFile(const char * filepath)
{
if(!filepath)
return 0;
struct stat filestat;
char dirnoslash[strlen(filepath)+2];
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
while(dirnoslash[strlen(dirnoslash)-1] == '/')
dirnoslash[strlen(dirnoslash)-1] = '\0';
char * notRoot = strrchr(dirnoslash, '/');
if(!notRoot)
{
strcat(dirnoslash, "/");
}
if (stat(dirnoslash, &filestat) == 0)
return 1;
return 0;
}
int CreateSubfolder(const char * fullpath)
{
if(!fullpath)
return 0;
int result = 0;
char dirnoslash[strlen(fullpath)+1];
strcpy(dirnoslash, fullpath);
int pos = strlen(dirnoslash)-1;
while(dirnoslash[pos] == '/')
{
dirnoslash[pos] = '\0';
pos--;
}
if(CheckFile(dirnoslash))
{
return 1;
}
else
{
char parentpath[strlen(dirnoslash)+2];
strcpy(parentpath, dirnoslash);
char * ptr = strrchr(parentpath, '/');
if(!ptr)
{
//!Device root directory (must be with '/')
strcat(parentpath, "/");
struct stat filestat;
if (stat(parentpath, &filestat) == 0)
return 1;
return 0;
}
ptr++;
ptr[0] = '\0';
result = CreateSubfolder(parentpath);
}
if(!result)
return 0;
if (mkdir(dirnoslash, 0777) == -1)
{
return 0;
}
return 1;
}

View File

@ -1,23 +0,0 @@
#ifndef __FS_UTILS_H_
#define __FS_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "dynamic_libs/os_types.h"
int MountFS(void *pClient, void *pCmd, char **mount_path);
int UmountFS(void *pClient, void *pCmd, const char *mountPath);
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size);
//! todo: C++ class
int CreateSubfolder(const char * fullpath);
int CheckFile(const char * filepath);
#ifdef __cplusplus
}
#endif
#endif // __FS_UTILS_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
/***************************************************************************
* Copyright (C) 2015
* 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 __SD_FAT_DEVOPTAB_H_
#define __SD_FAT_DEVOPTAB_H_
#ifdef __cplusplus
extern "C" {
#endif
int mount_sd_fat(const char *path);
int unmount_sd_fat(const char *path);
#ifdef __cplusplus
}
#endif
#endif // __SD_FAT_DEVOPTAB_H_

View File

@ -1,7 +1,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "dynamic_libs/os_functions.h"
#include "ios_exploit.h" #include "ios_exploit.h"
#include "main.h"
#define ALIGN4(x) (((x) + 3) & ~3) #define ALIGN4(x) (((x) + 3) & ~3)
@ -13,10 +13,10 @@
#define ARM_CODE_BASE 0x08135000 #define ARM_CODE_BASE 0x08135000
#define REPLACE_SYSCALL 0x081298BC #define REPLACE_SYSCALL 0x081298BC
extern const u8 launch_image_tga[]; extern const uint8_t launch_image_tga[];
extern const u32 launch_image_tga_size; extern const uint32_t launch_image_tga_size;
static void uhs_exploit_init(int uhs_handle, cfw_config_t * config); static void uhs_exploit_init(int uhs_handle);
static int uhs_write32(int uhs_handle, int arm_addr, int val); static int uhs_write32(int uhs_handle, int arm_addr, int val);
//!------Variables used in exploit------ //!------Variables used in exploit------
@ -26,17 +26,14 @@ static int *ayylmao = (int*)0xF4500000;
typedef struct typedef struct
{ {
u32 size; uint32_t size;
u8 data[0]; uint8_t data[0];
} payload_info_t; } payload_info_t;
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ /* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
#include "../ios_kernel/ios_kernel.bin.h" #include "../ios_kernel/ios_kernel.bin.h"
#include "../ios_usb/ios_usb.bin.h" #include "../ios_usb/ios_usb.bin.h"
#include "../ios_fs/ios_fs.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) */
@ -306,8 +303,16 @@ static const int second_chain[] = {
0x1012EA68, // 0xAC stack pivot 0x1012EA68, // 0xAC stack pivot
}; };
static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) static void uhs_exploit_init(int dev_uhs_0_handle){
{
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
void (* DCStoreRange)(const void *addr, uint32_t length);
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
ayylmao[5] = 1; ayylmao[5] = 1;
ayylmao[8] = 0x500000; ayylmao[8] = 0x500000;
@ -317,49 +322,14 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
payload_info_t *payloads = (payload_info_t*)0xF4148000; payload_info_t *payloads = (payload_info_t*)0xF4148000;
payloads->size = sizeof(cfw_config_t);
memcpy(payloads->data, config, payloads->size);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
payloads->size = sizeof(ios_usb_bin); payloads->size = sizeof(ios_usb_bin);
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) );
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_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); payloads->size = sizeof(ios_mcp_bin);
memcpy(payloads->data, ios_mcp_bin, payloads->size); memcpy(payloads->data, ios_mcp_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->launchImage)
{
FILE *pFile = fopen(APP_PATH "/launch_image.tga", "rb");
if(pFile)
{
fseek(pFile, 0, SEEK_END);
payloads->size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
fread(payloads->data, 1, payloads->size, pFile);
fclose(pFile);
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
}
else
{
payloads->size = launch_image_tga_size;
memcpy(payloads->data, launch_image_tga, 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;
@ -367,11 +337,22 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
DCStoreRange((void*)0xF4120000, sizeof(second_chain)); DCStoreRange((void*)0xF4120000, sizeof(second_chain));
DCStoreRange((void*)0xF4130000, sizeof(final_chain)); DCStoreRange((void*)0xF4130000, sizeof(final_chain));
DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin)); DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin));
DCStoreRange((void*)0xF4148000, ((u32)payloads) - 0xF4148000); DCStoreRange((void*)0xF4148000, ((uint32_t)payloads) - 0xF4148000);
} }
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val){
{ unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
void (* DCStoreRange)(const void *addr, uint32_t length);
int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
void (* OSSleepTicks)(uint64_t length);
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress)
OSSleepTicks(0x200000); //! Improves stability OSSleepTicks(0x200000); //! Improves stability
@ -380,8 +361,20 @@ static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val)
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
} }
int ExecuteIOSExploit(cfw_config_t * config) int ExecuteIOSExploit(){
{
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
int (*IOS_Open)(char *path, unsigned int mode);
int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
int (*IOS_Close)(int fd);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close);
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
if(iosuhaxFd >= 0) if(iosuhaxFd >= 0)
{ {
@ -397,10 +390,11 @@ int ExecuteIOSExploit(cfw_config_t * config)
//! execute exploit //! execute exploit
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
if(dev_uhs_0_handle < 0) if(dev_uhs_0_handle < 0){
return dev_uhs_0_handle; return dev_uhs_0_handle;
}
uhs_exploit_init(dev_uhs_0_handle, config); uhs_exploit_init(dev_uhs_0_handle);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); 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 + 0x10, 0x1011814C);
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);

View File

@ -1,13 +1,11 @@
#ifndef _IOS_EXPLOIT_H_ #ifndef _IOS_EXPLOIT_H_
#define _IOS_EXPLOIT_H_ #define _IOS_EXPLOIT_H_
#include "cfw_config.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
int ExecuteIOSExploit(cfw_config_t * config); int ExecuteIOSExploit();
#ifdef __cplusplus #ifdef __cplusplus
} }

239
src/kernel_asm.S Normal file
View File

@ -0,0 +1,239 @@
.section ".kernel_code"
.globl SaveAndResetDataBATs_And_SRs_hook
SaveAndResetDataBATs_And_SRs_hook:
# setup CTR to the position we need to return to
mflr r5
mtctr r5
# set link register to its original value
mtlr r7
# setup us a nice DBAT for our code data with same region as our code
mfspr r5, 560
mtspr 570, r5
mfspr r5, 561
mtspr 571, r5
# restore the original kernel instructions that we replaced
lwz r5, 0x34(r3)
lwz r6, 0x38(r3)
lwz r7, 0x3C(r3)
lwz r8, 0x40(r3)
lwz r9, 0x44(r3)
lwz r10, 0x48(r3)
lwz r11, 0x4C(r3)
lwz r3, 0x50(r3)
isync
mtsr 7, r5
# jump back to the position in kernel after our patch (from LR)
bctr
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06B6C
#define BAT_SET_NOP_ADDR_2 0xFFF06BF8
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D70C
#define BAT_SET_NOP_ADDR_6 0xFFF1D728
#define BAT_SET_NOP_ADDR_7 0xFFF1D82C
#define BAT_SET_NOP_ADDR_8 0xFFEE11C4
#define BAT_SET_NOP_ADDR_9 0xFFEE11C8
#define BAT_SETUP_HOOK_ENTRY 0x00800000
#define BAT4U_VAL 0x008000FF
#define BAT4L_VAL 0x30800012
#define SET_R4_TO_ADDR(addr) \
lis r3, addr@h ; \
ori r3, r3, addr@l ; \
stw r4, 0(r3) ; \
dcbf 0, r3 ; \
icbi 0, r3 ;
.globl Syscall_0x36
Syscall_0x36:
li r0, 0x3600
sc
blr
.global SCKernelCopyData
SCKernelCopyData:
// Disable data address translation
mfmsr %r6
li %r7, 0x10
andc %r6, %r6, %r7
mtmsr %r6
// Copy data
addi %r3, %r3, -1
addi %r4, %r4, -1
mtctr %r5
SCKernelCopyData_loop:
lbzu %r5, 1(%r4)
stbu %r5, 1(%r3)
bdnz SCKernelCopyData_loop
// Enable data address translation
ori %r6, %r6, 0x10
mtmsr %r6
blr
.global SC_0x25_KernelCopyData
SC_0x25_KernelCopyData:
li %r0, 0x2500
sc
blr
.globl KernelPatches
KernelPatches:
# store the old DBAT0
mfdbatu r5, 0
mfdbatl r6, 0
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFF0
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFF0
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
# just chosen because its simple
lis r3, BAT_SETUP_HOOK_ADDR@h
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
# make the kernel setup our section in IBAT4 and
# jump to our function to restore the replaced instructions
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
ori r4, r4, BAT4L_VAL@h
stw r4, 0x00(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
ori r4, r4, BAT4L_VAL@l
stw r4, 0x04(r3)
lis r4, 0x7cf1 # mtspr 561, r7
ori r4, r4, 0x8ba6
stw r4, 0x08(r3)
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
ori r4, r4, BAT4U_VAL@h
stw r4, 0x0C(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
ori r4, r4, BAT4U_VAL@l
stw r4, 0x10(r3)
lis r4, 0x7cf0 # mtspr 560, r7
ori r4, r4, 0x8ba6
stw r4, 0x14(r3)
lis r4, 0x7c00 # eieio
ori r4, r4, 0x06ac
stw r4, 0x18(r3)
lis r4, 0x4c00 # isync
ori r4, r4, 0x012c
stw r4, 0x1C(r3)
lis r4, 0x7ce8 # mflr r7
ori r4, r4, 0x02a6
stw r4, 0x20(r3)
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
stw r4, 0x24(r3)
# flush and invalidate the replaced instructions
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
dcbf 0, r3
icbi 0, r3
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
dcbf 0, r3
icbi 0, r3
sync
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
# IBATL 4
lis r3, BAT4L_VAL@h
ori r3, r3, BAT4L_VAL@l
mtspr 561, r3
# IBATU 4
lis r3, BAT4U_VAL@h
ori r3, r3, BAT4U_VAL@l
mtspr 560, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
# nop on IBATU 4 and DBAT 5 set/reset
#ifdef BAT_SET_NOP_ADDR_1
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
#endif
#ifdef BAT_SET_NOP_ADDR_2
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
#endif
#ifdef BAT_SET_NOP_ADDR_3
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
#endif
#ifdef BAT_SET_NOP_ADDR_4
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
#endif
#ifdef BAT_SET_NOP_ADDR_5
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
#endif
#ifdef BAT_SET_NOP_ADDR_6
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
#endif
#ifdef BAT_SET_NOP_ADDR_7
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
#endif
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFEE
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFEE
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
#endif
# memory barrier
eieio
isync
# restore DBAT 0 and return from interrupt
mtdbatu 0, r5
mtdbatl 0, r6
# memory barrier
eieio
isync
blr

View File

@ -1,40 +1,23 @@
OUTPUT(ftpiiu.elf); OUTPUT(payload.elf);
/* Tell linker where our application entry is so the garbage collect can work correct */ ENTRY(_start);
ENTRY(__entry_menu);
SECTIONS { SECTIONS {
. = 0x00802000; . = 0x00800000;
.text : { .text : {
*(.kernel_code*);
*(.text*); *(.text*);
} /* Tell linker to not garbage collect this section as it is not referenced anywhere */
.rodata : { KEEP(*(.kernel_code*));
*(.rodata*);
} }
.data : { .data : {
*(.rodata*);
*(.data*); *(.data*);
__sdata_start = .;
*(.sdata*);
__sdata_end = .;
__sdata2_start = .;
*(.sdata2*);
__sdata2_end = .;
}
.bss : {
__bss_start = .;
*(.bss*); *(.bss*);
*(.sbss*);
*(COMMON);
__bss_end = .;
} }
__CODE_END = .;
/DISCARD/ : { /DISCARD/ : {
*(*); *(*);
} }
} }
/******************************************************** FS ********************************************************/ ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x7C0000, "elf is too big");
/* coreinit.rpl difference in addresses 0xFE3C00 */

View File

@ -5,98 +5,145 @@
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/fs_functions.h"
#include "dynamic_libs/gx2_functions.h"
#include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "fs/fs_utils.h"
#include "fs/sd_fat_devoptab.h"
#include "system/memory.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "common/common.h"
#include "menu.h"
#include "main.h" #include "main.h"
#include "ios_exploit.h" #include "ios_exploit.h"
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
#define OSFatal ((void (*)(char* msg))0x01031618)
static int exitToHBLOnLaunch = 0; #define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__);
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
int Menu_Main(void) #define ADDRESS_OSTitle_main_entry_ptr 0x1005E040
{ #define ADDRESS_main_entry_hook 0x0101c56c
//!---------INIT---------
InitOSFunctionPointers();
InitSysFunctionPointers();
InitFSFunctionPointers();
InitSocketFunctionPointers();
InitVPadFunctionPointers();
u64 currenTitleId = OSGetTitleID(); #define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
// in case we are not in mii maker or HBL channel but in system menu or another channel we need to exit here /* assembly functions */
if (currenTitleId != 0x000500101004A200 && // mii maker eur extern void Syscall_0x36(void);
currenTitleId != 0x000500101004A100 && // mii maker usa extern void KernelPatches(void);
currenTitleId != 0x000500101004A000 && // mii maker jpn extern void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
currenTitleId != 0x0005000013374842) // HBL channel
{ extern void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
return EXIT_RELAUNCH_ON_LOAD;
} void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
else if(exitToHBLOnLaunch)
{ typedef struct _private_data_t {
return 0; EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align);
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s);
EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s);
EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*);
EXPORT_DECL(void, exit, int);
EXPORT_DECL(void, DCInvalidateRange, const void *addr, unsigned int length);
EXPORT_DECL(void, DCFlushRange, const void *addr, unsigned int length);
EXPORT_DECL(void, ICInvalidateRange, const void *addr, unsigned int length);
EXPORT_DECL(void, OSForceFullRelaunch);
EXPORT_DECL(void, SYSRelaunchTitle, int argc, char** argv);
EXPORT_DECL(void, SYSLaunchMenu);
} private_data_t;
static void loadFunctionPointers(private_data_t * private_data) {
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit", &coreinit_handle);
unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr;
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange);
OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", private_data->DCInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", private_data->ICInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "OSEffectiveToPhysical", private_data->OSEffectiveToPhysical);
OS_FIND_EXPORT(coreinit_handle, "OSForceFullRelaunch", private_data->OSForceFullRelaunch);
OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit);
unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle);
OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu);
} }
VPADInit(); void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) {
int forceMenu = 0; pdata->ICInvalidateRange(&value, 4);
pdata->DCFlushRange(&value, 4);
{ uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *)addr);
VPADData vpad; uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *)&value);
int vpadError = -1;
VPADRead(0, &vpad, 1, &vpadError);
if(vpadError == 0) SC_0x25_KernelCopyData(dst, src, 4);
{
forceMenu = (vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_B; pdata->DCFlushRange((void *)addr, 4);
} pdata->ICInvalidateRange((void *)addr, 4);
} }
mount_sd_fat("sd"); int _start(int argc, char **argv) {
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
cfw_config_t config; kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int)KernelPatches);
default_config(&config); kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int)KernelPatches);
read_config(&config); kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int)KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int)KernelPatches);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int)KernelPatches);
int launch = 1; Syscall_0x36();
if(forceMenu || config.directLaunch == 0) ExecuteIOSExploit();
{
launch = ShowMenu(&config); private_data_t private_data;
loadFunctionPointers(&private_data);
unsigned int repl_addr = ADDRESS_main_entry_hook;
unsigned int bufferU32 = 0x4E800421;
KernelWriteU32(repl_addr,bufferU32,&private_data);
// restart mii maker.
//private_data.SYSRelaunchTitle(0, 0);
//private_data.exit(0);
private_data.OSForceFullRelaunch();
private_data.SYSLaunchMenu();
return ( (int (*)(int, char **))(*(unsigned int*)0x1005E040) )(argc, argv);
} }
int returnCode = 0; /* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
if(launch) asm volatile (
{ "li 3,1\n"
int res = ExecuteIOSExploit(&config); "li 4,0\n"
if(res == 0) "mr 5,%1\n"
{ "li 6,0\n"
if(config.noIosReload == 0) "li 7,0\n"
{ "lis 8,1\n"
OSForceFullRelaunch(); "mr 9,%0\n"
SYSLaunchMenu(); "mr %1,1\n"
returnCode = EXIT_RELAUNCH_ON_LOAD; "li 0,0x3500\n"
} "sc\n"
else if(config.launchSysMenu) "nop\n"
{ "mr 1,%1\n"
SYSLaunchMenu(); :
exitToHBLOnLaunch = 1; : "r"(addr), "r"(value)
returnCode = EXIT_RELAUNCH_ON_LOAD; : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
} "11", "12"
} );
}
unmount_sd_fat("sd");
return returnCode;
} }

View File

@ -2,14 +2,16 @@
#ifndef _MAIN_H_ #ifndef _MAIN_H_
#define _MAIN_H_ #define _MAIN_H_
#include "common/types.h"
#include "dynamic_libs/os_functions.h"
/* Main */ /* Main */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
//! C wrapper for our C++ functions //! C wrapper for our C++ functions
int Menu_Main(void); int Menu_Main(void);

View File

@ -1,259 +0,0 @@
/***************************************************************************
* 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 <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/fs_functions.h"
#include "dynamic_libs/gx2_functions.h"
#include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "menu.h"
#define MAX_CONFIG_SETTINGS_EXPERT 9
#define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)
#define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2))
struct {
const char *option;
const char *enabled;
const char *disabled;
} selection_options[] =
{
{ "Config view mode", "expert", "default" },
{ "Skip this menu on launch", "on", "off" },
{ "Show launch image", "on", "off" },
{ "Don't relaunch OS", "on", "off" },
{ "Launch System Menu", "on", "off" },
{ "redNAND", "on", "off" },
{ "SEEPROM redirection", "on", "off" },
{ "OTP redirection", "on", "off" },
{ "Use syshax.xml (coldboothax)", "on", "off" },
};
static void console_print_pos(int x, int y, const char *format, ...)
{
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
if(strlen(tmp) > 79)
tmp[79] = 0;
OSScreenPutFontEx(0, x, y, tmp);
OSScreenPutFontEx(1, x, y, tmp);
}
va_end(va);
if(tmp)
free(tmp);
}
int ShowMenu(cfw_config_t * currentConfig)
{
// Init screen and screen buffers
OSScreenInit();
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
u8 * screenBuffer = (u8*) memalign(0x100, screen_buf0_size + screen_buf1_size);
OSScreenSetBufferEx(0, (void *)screenBuffer);
OSScreenSetBufferEx(1, (void *)(screenBuffer + screen_buf0_size));
OSScreenEnableEx(0, 1);
OSScreenEnableEx(1, 1);
// Clear screens
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
VPADData vpad;
int vpadError;
int x_offset = -2;
int initScreen = 1;
int selected = 0;
int launch = 0;
cfw_config_t config;
memcpy(&config, currentConfig, sizeof(cfw_config_t));
int max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT;
while(1)
{
//! update only at 50 Hz, thats more than enough
vpadError = -1;
VPADRead(0, &vpad, 1, &vpadError);
if(vpadError == 0)
{
if(vpad.btns_d & VPAD_BUTTON_HOME)
{
break;
}
else if(vpad.btns_d & VPAD_BUTTON_A)
{
launch = 1;
break;
}
else if(vpad.btns_d & VPAD_BUTTON_DOWN)
{
selected++;
if(selected >= max_config_item)
selected = 0;
initScreen = 1;
}
else if(vpad.btns_d & VPAD_BUTTON_UP)
{
selected--;
if(selected < 0)
selected = max_config_item - 1;
initScreen = 1;
}
else if(vpad.btns_d & (VPAD_BUTTON_LEFT | VPAD_BUTTON_RIGHT))
{
switch(selected)
{
case 0:
config.viewMode = !config.viewMode;
max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT;
break;
case 1:
config.directLaunch = !config.directLaunch;
break;
case 2:
config.launchImage = !config.launchImage;
break;
case 3:
config.noIosReload = !config.noIosReload;
break;
case 4:
config.launchSysMenu = !config.launchSysMenu;
break;
case 5:
config.redNAND = !config.redNAND;
break;
case 6:
config.seeprom_red = !config.seeprom_red;
break;
case 7:
config.otp_red = !config.otp_red;
break;
case 8:
config.syshaxXml = !config.syshaxXml;
break;
default:
break;
}
if(!config.viewMode)
{
config.syshaxXml = 0;
if(config.redNAND)
{
config.seeprom_red = 1;
config.otp_red = 1;
}
}
if(config.noIosReload)
{
config.launchImage = 0;
config.redNAND = 0;
}
else
{
config.launchSysMenu = 1;
}
if(config.redNAND == 0)
{
config.seeprom_red = 0;
config.otp_red = 0;
}
initScreen = 1;
}
}
if(initScreen)
{
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
console_print_pos(x_offset, 1, " -- MOCHA CFW %s by Dimok --", APP_VERSION);
console_print_pos(x_offset, 3, "Select your options and press A to launch.");
console_print_pos(x_offset, 4, "Press HOME to exit back to HBL.");
console_print_pos(x_offset, 5, "Hold B on start to force enter this menu");
int y_offset = 6;
int option_count = sizeof(selection_options) / sizeof(selection_options[0]);
int idx;
int * configPtr = &config.viewMode;
for(idx = 0; idx < option_count && idx < max_config_item; idx++)
{
console_print_pos(x_offset, y_offset++, "%s %-29s : %s%s%s %s%s%s", TEXT_SEL((selected == idx), "--->", " "), selection_options[idx].option,
TEXT_SEL(configPtr[idx], "<", " "), selection_options[idx].enabled, TEXT_SEL(configPtr[idx], ">", " "),
TEXT_SEL(configPtr[idx], " ", "<"), selection_options[idx].disabled, TEXT_SEL(configPtr[idx], " ", ">"));
}
console_print_pos(x_offset, 16, "Credits go to everyone who contributed to Wii U scene publicly.");
console_print_pos(x_offset, 17, "Special thanks to smealum, plutoo, yellows8, naehrwert and derrek.");
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
initScreen = 0;
}
os_usleep(20000);
}
OSScreenShutdown();
free(screenBuffer);
if(memcmp(currentConfig, &config, sizeof(cfw_config_t)) != 0)
{
memcpy(currentConfig, &config, sizeof(cfw_config_t));
write_config(currentConfig);
}
return launch;
}

View File

@ -1,8 +0,0 @@
#ifndef _MENU_H_
#define _MENU_H_
#include "cfw_config.h"
int ShowMenu(cfw_config_t * config);
#endif

View File

@ -1,145 +0,0 @@
#include <stdio.h>
#include "dynamic_libs/os_functions.h"
#include "utils/logger.h"
#include "exception_handler.h"
#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4
#define OS_EXCEPTION_DSI 2
#define OS_EXCEPTION_ISI 3
#define OS_EXCEPTION_PROGRAM 6
#define CPU_STACK_TRACE_DEPTH 10
#define __stringify(rn) #rn
#define mfspr(_rn) \
({ register uint32_t _rval = 0; \
asm volatile("mfspr %0," __stringify(_rn) \
: "=r" (_rval));\
_rval; \
})
typedef struct _framerec {
struct _framerec *up;
void *lr;
} frame_rec, *frame_rec_t;
static const char *exception_names[] = {
"DSI",
"ISI",
"PROGRAM"
};
static const char exception_print_formats[18][45] = {
"Exception type %s occurred!\n", // 0
"GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1
"GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2
"GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3
"GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4
"GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5
"GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6
"GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7
"GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8
"LR %08X SRR0 %08x SRR1 %08x\n", // 9
"DAR %08X DSISR %08X\n", // 10
"\nSTACK DUMP:", // 11
" --> ", // 12
" -->\n", // 13
"\n", // 14
"%p", // 15
"\nCODE DUMP:\n", // 16
"%p: %08X %08X %08X %08X\n", // 17
};
static unsigned char exception_cb(void * c, unsigned char exception_type) {
char buf[850];
int pos = 0;
OSContext *context = (OSContext *) c;
/*
* This part is mostly from libogc. Thanks to the devs over there.
*/
pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]);
pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16], context->gpr[24]);
pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17], context->gpr[25]);
pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18], context->gpr[26]);
pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19], context->gpr[27]);
pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20], context->gpr[28]);
pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21], context->gpr[29]);
pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22], context->gpr[30]);
pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23], context->gpr[31]);
pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1);
//if(exception_type == OS_EXCEPTION_DSI) {
pos += sprintf(buf + pos, exception_print_formats[10], context->ex1, context->ex0); // this freezes
//}
void *pc = (void*)context->srr0;
void *lr = (void*)context->lr;
void *r1 = (void*)context->gpr[1];
register uint32_t i = 0;
register frame_rec_t l,p = (frame_rec_t)lr;
l = p;
p = r1;
if(!p)
asm volatile("mr %0,%%r1" : "=r"(p));
pos += sprintf(buf + pos, exception_print_formats[11]);
for(i = 0; i < CPU_STACK_TRACE_DEPTH-1 && p->up; p = p->up, i++) {
if(i % 4)
pos += sprintf(buf + pos, exception_print_formats[12]);
else {
if(i > 0)
pos += sprintf(buf + pos, exception_print_formats[13]);
else
pos += sprintf(buf + pos, exception_print_formats[14]);
}
switch(i) {
case 0:
if(pc)
pos += sprintf(buf + pos, exception_print_formats[15],pc);
break;
case 1:
if(!l)
l = (frame_rec_t)mfspr(8);
pos += sprintf(buf + pos, exception_print_formats[15],(void*)l);
break;
default:
pos += sprintf(buf + pos, exception_print_formats[15],(void*)(p->up->lr));
break;
}
}
//if(exception_type == OS_EXCEPTION_DSI) {
uint32_t *pAdd = (uint32_t*)context->srr0;
pos += sprintf(buf + pos, exception_print_formats[16]);
// TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen
for (i = 0; i < 8; i += 4)
pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]);
//}
#if DEBUG_LOGGER == 1
log_print(buf);
#endif
OSFatal(buf);
return 1;
}
static unsigned char dsi_exception_cb(void * context) {
return exception_cb(context, 0);
}
static unsigned char isi_exception_cb(void * context) {
return exception_cb(context, 1);
}
static unsigned char program_exception_cb(void * context) {
return exception_cb(context, 2);
}
void setup_os_exceptions(void) {
OSSetExceptionCallback(OS_EXCEPTION_DSI, &dsi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_ISI, &isi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb);
}

View File

@ -1,14 +0,0 @@
#ifndef __EXCEPTION_HANDLER_H_
#define __EXCEPTION_HANDLER_H_
#ifdef __cplusplus
extern "C" {
#endif
void setup_os_exceptions(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,181 +0,0 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "dynamic_libs/os_functions.h"
#include "common/common.h"
#include "memory.h"
#define MEMORY_ARENA_1 0
#define MEMORY_ARENA_2 1
#define MEMORY_ARENA_3 2
#define MEMORY_ARENA_4 3
#define MEMORY_ARENA_5 4
#define MEMORY_ARENA_6 5
#define MEMORY_ARENA_7 6
#define MEMORY_ARENA_8 7
#define MEMORY_ARENA_FG_BUCKET 8
static int mem1_heap = -1;
static int bucket_heap = -1;
void memoryInitialize(void)
{
int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1);
unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4);
void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4);
if(mem1_memory)
mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0);
int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET);
unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4);
void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4);
if(bucket_memory)
bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0);
}
void memoryRelease(void)
{
MEMDestroyExpHeap(mem1_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3);
mem1_heap = -1;
MEMDestroyExpHeap(bucket_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3);
bucket_heap = -1;
}
//!-------------------------------------------------------------------------------------------
//! wraps
//!-------------------------------------------------------------------------------------------
void *__wrap_malloc(size_t size)
{
// pointer to a function resolve
return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size);
}
void *__wrap_memalign(size_t align, size_t size)
{
if (align < 4)
align = 4;
// pointer to a function resolve
return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align);
}
void __wrap_free(void *p)
{
// pointer to a function resolve
if(p != 0)
((void (*)(void *))(*pMEMFreeToDefaultHeap))(p);
}
void *__wrap_calloc(size_t n, size_t size)
{
void *p = __wrap_malloc(n * size);
if (p != 0) {
memset(p, 0, n * size);
}
return p;
}
size_t __wrap_malloc_usable_size(void *p)
{
//! TODO: this is totally wrong and needs to be addressed
return 0x7FFFFFFF;
}
void *__wrap_realloc(void *p, size_t size)
{
void *new_ptr = __wrap_malloc(size);
if (new_ptr != 0)
{
memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size);
__wrap_free(p);
}
return new_ptr;
}
//!-------------------------------------------------------------------------------------------
//! reent versions
//!-------------------------------------------------------------------------------------------
void *__wrap__malloc_r(struct _reent *r, size_t size)
{
return __wrap_malloc(size);
}
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
{
return __wrap_calloc(n, size);
}
void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size)
{
return __wrap_memalign(align, size);
}
void __wrap__free_r(struct _reent *r, void *p)
{
__wrap_free(p);
}
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
{
return __wrap_malloc_usable_size(p);
}
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
{
return __wrap_realloc(p, size);
}
//!-------------------------------------------------------------------------------------------
//! some wrappers
//!-------------------------------------------------------------------------------------------
void * MEM2_alloc(unsigned int size, unsigned int align)
{
return __wrap_memalign(align, size);
}
void MEM2_free(void *ptr)
{
__wrap_free(ptr);
}
void * MEM1_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(mem1_heap, size, align);
}
void MEM1_free(void *ptr)
{
MEMFreeToExpHeap(mem1_heap, ptr);
}
void * MEMBucket_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(bucket_heap, size, align);
}
void MEMBucket_free(void *ptr)
{
MEMFreeToExpHeap(bucket_heap, ptr);
}

View File

@ -1,42 +0,0 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
void memoryInitialize(void);
void memoryRelease(void);
void * MEM2_alloc(unsigned int size, unsigned int align);
void MEM2_free(void *ptr);
void * MEM1_alloc(unsigned int size, unsigned int align);
void MEM1_free(void *ptr);
void * MEMBucket_alloc(unsigned int size, unsigned int align);
void MEMBucket_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // __MEMORY_H_

View File

@ -1,89 +0,0 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "logger.h"
#ifdef DEBUG_LOGGER
static int log_socket = -1;
static volatile int log_lock = 0;
void log_init(const char * ipString)
{
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
inet_aton(ipString, &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_deinit(void)
{
if(log_socket >= 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_print(const char *str)
{
// socket is always 0 initially as it is in the BSS
if(log_socket < 0) {
return;
}
while(log_lock)
usleep(1000);
log_lock = 1;
int len = strlen(str);
int ret;
while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
ret = send(log_socket, str, block, 0);
if(ret < 0)
break;
len -= ret;
str += ret;
}
log_lock = 0;
}
void log_printf(const char *format, ...)
{
if(log_socket < 0) {
return;
}
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
log_print(tmp);
}
va_end(va);
if(tmp)
free(tmp);
}
#endif

View File

@ -1,26 +0,0 @@
#ifndef __LOGGER_H_
#define __LOGGER_H_
#ifdef __cplusplus
extern "C" {
#endif
#define DEBUG_LOGGER 1
#ifdef DEBUG_LOGGER
void log_init(const char * ip);
void log_deinit(void);
void log_print(const char *str);
void log_printf(const char *format, ...);
#else
#define log_init(x)
#define log_deinit()
#define log_print(x)
#define log_printf(x, ...)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,47 +0,0 @@
#ifndef __UTILS_H_
#define __UTILS_H_
#include <malloc.h>
#include "../common/types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \
"icbi %0, %1\n" \
"sync\n" \
"eieio\n" \
"isync\n" \
: \
:"r"(0), "r"(((addr) & ~31)) \
:"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \
);
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
})
#define DegToRad(a) ( (a) * 0.01745329252f )
#define RadToDeg(a) ( (a) * 57.29577951f )
#define ALIGN4(x) (((x) + 3) & ~3)
#define ALIGN32(x) (((x) + 31) & ~31)
// those work only in powers of 2
#define ROUNDDOWN(val, align) ((val) & ~(align-1))
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align)
#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8)))
#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16)))
#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
#ifdef __cplusplus
}
#endif
#endif // __UTILS_H_