diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d2c8e50 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +.PHONY := all haxchi/haxchi_code.bin + +all: haxchi.srl + +haxchi/haxchi_code.bin: + @cd haxchi_code && make clean && make && cd .. + +haxchi_rop_hook.bin haxchi_rop.bin: haxchi/haxchi_code.bin haxchi_rop.s + armips haxchi_rop.s + +haxchi.srl: haxchi_rop_hook.bin haxchi_rop.bin haxchi.s + armips haxchi.s + +clean: + @rm -f *.bin haxchi.srl + @echo "all cleaned up !" diff --git a/haxchi.bat b/haxchi.bat new file mode 100644 index 0000000..e69de29 diff --git a/haxchi.s b/haxchi.s new file mode 100644 index 0000000..8555127 --- /dev/null +++ b/haxchi.s @@ -0,0 +1,41 @@ +.create "haxchi.srl", 0 +.nds + +hax_target_address equ 0x107968AC +code_target_address equ (0xF4000000 + 0xFD2000) + +.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 0x20000000 ; ARM9 entry_address + .word 0xEBBC0E00 + code_target_address ; ARM9 ram_address + .word arm9_data_end - arm9_data ; ARM9 size + .word arm7_data ; ARM7 rom_offset + .word 0x2000000 ; ARM7 entry_address + .word 0xEBBC0E00 + 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.bin" +arm9_data_end: + +.align 0x1000 +arm7_data: + .incbin "haxchi_rop_hook.bin" +arm7_data_end: + +total_size: + +.Close diff --git a/haxchi_code/Makefile b/haxchi_code/Makefile new file mode 100644 index 0000000..96ed0c2 --- /dev/null +++ b/haxchi_code/Makefile @@ -0,0 +1,66 @@ +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +ifeq ($(filter $(DEVKITPPC)/bin,$(PATH)),) +export PATH:=$(DEVKITPPC)/bin:$(PATH) +endif + +CC = powerpc-eabi-gcc +LINK = powerpc-eabi-ld +AS = powerpc-eabi-as +OBJCOPY = powerpc-eabi-objcopy +CFLAGS += -Wall -mbig-endian -mcpu=750 -meabi -std=c99 -O2 +LDFLAGS += --script=ccd00.ld -EB -L"$(DEVKITPPC)/powerpc-eabi/lib" -Map=output.map -lm -lg -lc + +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 devkitPPC +#--------------------------------------------------------------------------------- +define bin2o + bin2s $< | $(AS) -o $(@) + echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( build/$*.d + +build/%.o: source/%.s + $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo $(notdir $<) + @$(bin2o) diff --git a/haxchi_code/ccd00.ld b/haxchi_code/ccd00.ld new file mode 100644 index 0000000..9c4fa3b --- /dev/null +++ b/haxchi_code/ccd00.ld @@ -0,0 +1,25 @@ +OUTPUT_ARCH(powerpc) + +MEMORY +{ + RAMX (rx) : ORIGIN = 0x01800000, LENGTH = 0x00010000 + RAMRW (rw!i) : ORIGIN = 0x20000000, LENGTH = 0x00002000 +} + +SECTIONS +{ + .text : ALIGN(0x100) { + build/crt0.o(.init) + *(.text) + *(.rodata) + *(.sdata) + } + + .bss : { + _bss_start = .; + *(.bss); + *(.sbss); + } + _bss_end = .; +} + diff --git a/haxchi_code/ccd00.specs b/haxchi_code/ccd00.specs new file mode 100644 index 0000000..ccff243 --- /dev/null +++ b/haxchi_code/ccd00.specs @@ -0,0 +1,4 @@ +%rename link old_link + +*link: +%(old_link) -T ./ccd00.ld%s diff --git a/haxchi_code/source/constants.h b/haxchi_code/source/constants.h new file mode 100644 index 0000000..7bc0c03 --- /dev/null +++ b/haxchi_code/source/constants.h @@ -0,0 +1,71 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + #define CCR_MEMCPY 301478892 + #define CCR_MEMSET 301479048 + #define CCR_STRNCPY 301481600 + #define CCR_MOV_R0R4_POP_R4PC 301461596 + #define CCR_LDR_R0R0x8_BLX_R3_POP_PC 301138616 + #define CCR_ROP_R4R5R6R7R8PC 300950884 + #define CCR_ROP_R4R5R6R7PC 300949720 + #define CCR_MOV_R0R7_MOV_R1R8_MOV_R2R4_BLX_R5 301028284 + #define CCR_MOV_R1R8_MOV_R2R4_BLX_R5 ((CCR_MOV_R0R7_MOV_R1R8_MOV_R2R4_BLX_R5 + 0x4)) + #define CCR_BLX_R2_POP_R4PC 301137492 + #define CCR_BLX_R6_POP_R4R5R6PC 301004128 + #define CCR_BLX_R4 300999020 + #define CCR_STR_R0R4x24_POP_R4PC 301277360 + #define CCR_STR_R3R5x24_POP_R4R5PC 301294364 + #define CCR_POP_R4PC 301277364 + #define CCR_LDR_R0R5x18_BLX_R7 301319000 + #define CCR_POP_R4R5PC 301139088 + #define CCR_POP_R3R5PC 301159067 + #define CCR_POP_R4R5R6PC 301004132 + #define CCR_POP_R4R5R6R7PC 300949720 + #define CCR_POP_PC 300948676 + #define CCR_LDR_R0R7_POP_R4R5R6R7R8R9R10PC 301375148 + #define CCR_MOV_R0R9_POP_ADD_SPxC_R4R5R6R7R8R9R10R11PC 301365520 + #define CCR_LDM_SPR0R1_ADD_SPx14_POP_R4R5R6R7R8R9R10R11LR_BX_LR 301485876 + #define CCR_MVNSNE_SPR4RORx13_BX_LR 301204712 + #define CCR_CMP_R3x0_POPEQ_PC_BLX_R3_POP_PC 300999264 + #define CCR_BLX_R4_POP_R4R5PC 301016140 + #define CCR_IOCTL_RET 301232392 + #define CCR_NFC_STACKTOP 303204396 + #define CCR_NFC_STACKSIZE 51168 + #define ROP_INITIAL_START_LR ((CCR_NFC_STACKTOP - 0x20 - (9 * 0x4 + 0x4) - 0x4)) + #define ROP_INITIAL_START ((ROP_INITIAL_START_LR + 0x4 + 0x8)) + #define CCR_FSA_HANDLE 301957260 + #define CCR_ROP_SVC_6 301477528 + #define CCR_ROP_SVC_CREATETHREAD 301477480 + #define CCR_ROP_SVC_IOCTL 301477928 + #define CCR_ROP_SVC_IOCTLV 301477936 + #define CCR_ROP_SVC_STARTTHREAD 301477536 + #define CCR_ROP_SVC_CREATEMESSAGEQUEUE 301477576 + #define CCR_ROP_SVC_JAMMESSAGEQUEUE 301477600 + #define CCR_ROP_SVC_CREATEHEAP 301477760 + #define CCR_ROP_SVC_FREEANDCLEAR 301477816 + #define CCR_ROP_SVC_4F 301478112 + #define CCR_ROP_SVC_RESOURCEREPLY0 301478064 + #define CCR_POP_R4LR_ROP_SVC_4F 301226192 + #define CCR_ROP_ALLOC_IOCTLBUF 301462868 + #define CCR_ROP_START 301232500 + #define KERNEL_SVC_81_HANDLER 135449900 + #define KERNEL_READ_OTP 135397960 + #define KERNEL_SET_DOMAIN 135457296 + #define KERNEL_DOMAIN_TABLE 135938048 + #define KERNEL_MEMCPY 135470340 + #define KERNEL_STRNLEN 135473816 + #define KERNEL_INVALIDATE_ICACHE 135453936 + #define FRAMEBUFFER_VA 0xF4000000 + #define FRAMEBUFFER_PA 0 + #define FRAMEBUFFER_SIZE 7372800 + #define ROP_SECONDARY_SIZE 4096 + #define ROP_SECONDARY_SRCBUF_VA 671088640 + #define ROP_SECONDARY_SRCBUF_PA (ROP_SECONDARY_SRCBUF_VA - 0x10000000 + 0x50000000) + #define ROP_SECONDARY_DSTBUF (CCR_NFC_STACKTOP - CCR_NFC_STACKSIZE) + #define DATABUFFER_VA ROP_SECONDARY_SRCBUF_VA+0x2000 + #define DATABUFFER_PA (DATABUFFER_VA - 0x10000000 + 0x50000000) + #define CCR_SHELLCODE_DST 0x11F85800 + #define MCP_SHELLCODE_DST 0x05059900 + #define SHELLCODE_SRC_VA ((ROP_SECONDARY_SRCBUF_VA+0x3000)) + #define SHELLCODE_SRC_PA (SHELLCODE_SRC_VA - 0x10000000 + 0x50000000) + #define SHELLCODE_DST 0xFFFFEC00 +#endif diff --git a/haxchi_code/source/crt0.s b/haxchi_code/source/crt0.s new file mode 100644 index 0000000..f994c8d --- /dev/null +++ b/haxchi_code/source/crt0.s @@ -0,0 +1,8 @@ +.section ".init" +.align 4 + +.extern _main +.type _main, %function + +_start: + b _main diff --git a/haxchi_code/source/imports.c b/haxchi_code/source/imports.c new file mode 100644 index 0000000..4f980c5 --- /dev/null +++ b/haxchi_code/source/imports.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include "imports.h" + +#define COREINIT_OFFSET (- 0xFE3C00) + +// dynamically linked +int (*IOS_Open)(const char* dev, int flags) = NULL; +int (*IOS_Ioctl)(int fd, u32 cmd, void* buf_in, u32 size_in, void* buf_out, u32 size_out) = NULL; +void (*DCFlushRange)(void *buffer, uint32_t length) = NULL; +int (*OSScreenClearBufferEx)(int bufferNum, u32 val) = NULL; +int (*OSScreenPutFontEx)(int bufferNum, unsigned int posX, unsigned int line, void* buffer) = NULL; +void (*OSFatal)(char*) = NULL; +void (*OSForceFullRelaunch)(void) = NULL; +void (*OSRestartGame)(void*, void*) = NULL; +int (*SYSLaunchMenu)(void) = NULL; +int (*SYSRelaunchTitle)(int, void*) = NULL; +int (*SYSLaunchSettings)(void*) = NULL; +int (*SYSSwitchToBrowser)(char*) = NULL; +int (*_SYSLaunchSettingsDirect)(void*) = NULL; +void (*Exit)(void) = NULL; +void (*_exit)(void) = NULL; +void (*OSScreenInit)(void) = NULL; +int (*OSScreenGetBufferSizeEx)(int bufferNum) = NULL; +int (*OSScreenSetBufferEx)(int bufferNum, void* addr) = NULL; +int (*OSScreenFlipBuffersEx)(int bufferNum) = NULL; +void* (*OSAllocFromSystem)(u32 size, int align) = NULL; +void (*OSFreeToSystem)(void *ptr) = NULL; +int (*IM_Open)() = NULL; +int (*IM_Close)(int fd) = NULL; +int (*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b) = NULL; +int (*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error); + +// 5.5.x values +int (*const OSDynLoad_Acquire)(const char* lib_name, int* out_addr) = (void*)(COREINIT_OFFSET + 0x0200DFB4); +int (*const OSDynLoad_FindExport)(int lib_handle, int flags, const char* name, void* out_addr) = (void*)(COREINIT_OFFSET + 0x0200F428); + +void init_imports() +{ + int coreinit_handle, sysapp_handle, vpad_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); + OSDynLoad_Acquire("vpad.rpl", &vpad_handle); + + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl); + + OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSFatal", &OSFatal); + OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch); + OSDynLoad_FindExport(coreinit_handle, 0, "OSRestartGame", &OSRestartGame); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSRelaunchTitle", &SYSRelaunchTitle); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchSettings", &SYSLaunchSettings); + OSDynLoad_FindExport(sysapp_handle, 0, "SYSSwitchToBrowser", &SYSSwitchToBrowser); + OSDynLoad_FindExport(sysapp_handle, 0, "_SYSLaunchSettingsDirect", &_SYSLaunchSettingsDirect); + OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &Exit); + OSDynLoad_FindExport(coreinit_handle, 0, "exit", &_exit); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); + OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); + OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open); + OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close); + OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState); + + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx); + OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx); + + OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead); +} + +void* memset(void *d, int v, size_t size) +{ + int i; + for(i = 0; i < size; i++) ((unsigned char*)d)[i] = v; + return d; +} + +void* memcpy(void *d, const void* s, size_t size) +{ + int i; + for(i = 0; i < size; i++) ((unsigned char*)d)[i] = ((unsigned char*)s)[i]; + return d; +} diff --git a/haxchi_code/source/imports.h b/haxchi_code/source/imports.h new file mode 100644 index 0000000..669b35e --- /dev/null +++ b/haxchi_code/source/imports.h @@ -0,0 +1,94 @@ +#ifndef IMPORTS_H +#define IMPORTS_H + +#include "types.h" +#include "constants.h" + +#define BSS_PHYS_OFFSET (0x50000000 - 0x10000000) +#define BSS_VA2PA(a) ((void*)(((u32)a) + BSS_PHYS_OFFSET)) +#define BSS_PA2VA(a) ((void*)(((u32)a) - BSS_PHYS_OFFSET)) + +extern void* _bss_start; +extern void* _bss_end; + +extern int (*IOS_Open)(const char* dev, int flags); +extern int (*IOS_Ioctl)(int fd, u32 cmd, void* buf_in, u32 size_in, void* buf_out, u32 size_out); + +extern void (*DCFlushRange)(void *buffer, uint32_t length); + +extern int (*OSScreenClearBufferEx)(int bufferNum, u32 val); +extern int (*OSScreenPutFontEx)(int bufferNum, unsigned int posX, unsigned int line, void* buffer); + +extern void (*OSFatal)(char*); +extern void (*OSForceFullRelaunch)(void); +extern int (*SYSLaunchMenu)(void); +extern int (*SYSRelaunchTitle)(int, void*); +extern int (*SYSLaunchSettings)(void*); +extern int (*SYSSwitchToBrowser)(char*); +extern int (*_SYSLaunchSettingsDirect)(void*); +extern void (*Exit)(void); +extern void (*_exit)(void); + +extern void* (*OSAllocFromSystem)(u32 size, int align); +extern void (*OSFreeToSystem)(void *ptr); +extern int (*IM_Open)(); +extern int (*IM_Close)(int fd); +extern int (*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b); + +extern void (*OSScreenInit)(void); +extern int (*OSScreenGetBufferSizeEx)(int bufferNum); +extern int (*OSScreenSetBufferEx)(int bufferNum, void* addr); +extern int (*OSScreenFlipBuffersEx)(int bufferNum); + +// the following (temporarily) stolen from libwiiu +#define BUTTON_A 0x8000 +#define BUTTON_B 0x4000 +#define BUTTON_X 0x2000 +#define BUTTON_Y 0x1000 +#define BUTTON_LEFT 0x0800 +#define BUTTON_RIGHT 0x0400 +#define BUTTON_UP 0x0200 +#define BUTTON_DOWN 0x0100 +#define BUTTON_ZL 0x0080 +#define BUTTON_ZR 0x0040 +#define BUTTON_L 0x0020 +#define BUTTON_R 0x0010 +#define BUTTON_PLUS 0x0008 +#define BUTTON_MINUS 0x0004 +#define BUTTON_HOME 0x0002 +#define BUTTON_SYNC 0x0001 + +typedef struct +{ + float x,y; +} Vec2D; + +typedef struct +{ + uint16_t x, y; /* Touch coordinates */ + uint16_t touched; /* 1 = Touched, 0 = Not touched */ + uint16_t validity; /* 0 = All valid, 1 = X invalid, 2 = Y invalid, 3 = Both invalid? */ +} VPADTPData; + +typedef struct +{ + uint32_t btn_hold; /* Held buttons */ + uint32_t btn_trigger; /* Buttons that are pressed at that instant */ + uint32_t btn_release; /* 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; + +extern int (*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error); + +void init_imports(); + +#endif diff --git a/haxchi_code/source/main.c b/haxchi_code/source/main.c new file mode 100644 index 0000000..359a3aa --- /dev/null +++ b/haxchi_code/source/main.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "imports.h" + +u32* framebuffer_tv; +u32* framebuffer_drc; +u32 framebuffer_tv_size; +u32 framebuffer_drc_size; + +void gfxInit() +{ + OSScreenInit(); + + framebuffer_tv_size = OSScreenGetBufferSizeEx(0); + framebuffer_drc_size = OSScreenGetBufferSizeEx(1); + + framebuffer_tv = (u32*)0xF4000000; + framebuffer_drc = (u32*)((void*)framebuffer_tv + framebuffer_tv_size); + + OSScreenSetBufferEx(0, framebuffer_tv); + OSScreenSetBufferEx(1, framebuffer_drc); +} + +void gfxFlip() +{ + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); +} + +void print(char* str, int x, int y) +{ + OSScreenPutFontEx(0, x, y, str); + OSScreenPutFontEx(1, x, y, str); +} + +void _main() +{ + // clear bss + memset(&_bss_start, 0x00, &_bss_end - &_bss_start); + + // get all the functions + init_imports(); + + // init framebuffers and stuff + gfxInit(); + + while(1) + { + VPADData vpad_data; + int vpad_error; + VPADRead(0, &vpad_data, 1, &vpad_error); + + OSScreenClearBufferEx(0, 0x40404040); + OSScreenClearBufferEx(1, 0x40404040); + + print("wii u got SPYND yo", 5, 5); + + int line = 7; + if (vpad_data.btn_hold & BUTTON_A) print("A is held", 7, line++); + if (vpad_data.btn_hold & BUTTON_B) print("B is held", 7, line++); + if (vpad_data.btn_hold & BUTTON_X) print("X is held", 7, line++); + if (vpad_data.btn_hold & BUTTON_Y) print("Y is held", 7, line++); + if (vpad_data.btn_hold & BUTTON_HOME) print("HOME is held", 7, line++); + + gfxFlip(); + } + + while(1); +} diff --git a/haxchi_code/source/types.h b/haxchi_code/source/types.h new file mode 100644 index 0000000..871e5dc --- /dev/null +++ b/haxchi_code/source/types.h @@ -0,0 +1,29 @@ +#ifndef TYPES_H +#define TYPES_H + + #include + #include + + #define U64_MAX UINT64_MAX + + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + + typedef int8_t s8; + typedef int16_t s16; + typedef int32_t s32; + typedef int64_t s64; + + typedef volatile u8 vu8; + typedef volatile u16 vu16; + typedef volatile u32 vu32; + typedef volatile u64 vu64; + + typedef volatile s8 vs8; + typedef volatile s16 vs16; + typedef volatile s32 vs32; + typedef volatile s64 vs64; + +#endif diff --git a/haxchi_rop.s b/haxchi_rop.s new file mode 100644 index 0000000..b277cb4 --- /dev/null +++ b/haxchi_rop.s @@ -0,0 +1,202 @@ +MAIN_STACKTOP equ (0x30796C00) +CORE0_STACKORIG equ (0x2B566050) ; TEMP ? +CORE0_ROPSTART equ (CORE0_STACKORIG + 0x2054) ; TEMP ? +RPX_OFFSET equ (0x01800000) +COREINIT_OFFSET equ (- 0xFE3C00) +LMW_R21R1xC_LWZ_R0R1x3C_MTLR_R0_ADDI_R1_x38_BLR equ (RPX_OFFSET + 0x02207084) +MTCTR_R28_ADDI_R6x68_MR_R5R29_R4R22_R3R21_BCTRL equ (RPX_OFFSET + 0x02206FA8) +BCTRL equ (RPX_OFFSET + 0x02206FBC) +MTCTR_R27_ADDI_R31x2_MR_R3R31_R4R30_R5R29_R6R28_BCTRL_LMW_R26R1x18_MTLR_R1x34_ADDI_R1x30_BLR equ (RPX_OFFSET + 0x020A3610) +LWZ_R0x104_MTLR_R0_ADDI_R1x100_BLR equ (RPX_OFFSET + 0x020E92C8) +LWZ_R0x2054_MTLR_R0_ADDI_R1x2050_BLR equ (RPX_OFFSET + 0x02026DE0) +LWZ_R0R1x14_LWZ_R30R1x8_R31R1xC_MTLR_R0_ADDI_R1x10_BLR equ (RPX_OFFSET + 0x020ACA38) +MR_R11R31_LMW_R26R1x8_LWZ_R0x24_MTLR_R0_ADDI_R1x20_CLRLWI_R3R11x18_BLR equ (RPX_OFFSET + 0x02179168) +LWZ_R0R11x4_R31R11xM4_MTLR_R0_MR_R1R11_BLR equ (RPX_OFFSET + 0x02277B44) +MTCTR_R30_MR_R8R21_R7R29_R6R28_R5R27_R4R25_R3R24_BCTRL equ (COREINIT_OFFSET + 0x02002968) + +NERD_CREATETHREAD equ (RPX_OFFSET + 0x022219E8) +NERD_STARTTHREAD equ (RPX_OFFSET + 0x02221E04) +HACHI_APPLICATION_SHUTDOWNANDDESTROY equ (RPX_OFFSET + 0x02006CC8) +HACHI_APPLICATION_PTR equ (0x10c8c938) + +OS_CREATETHREAD equ (0x02025764 + COREINIT_OFFSET) +OS_GETTHREADAFFINITY equ (0x020266A4 + COREINIT_OFFSET) +OS_FORCEFULLRELAUNCH equ (0x02019BA8 + COREINIT_OFFSET) +OSCODEGEN_GETVARANGE equ (0x0201B1C0 + COREINIT_OFFSET) +OSCODEGEN_SWITCHSECMODE equ (0x0201B2C0 + COREINIT_OFFSET) +MEMCPY equ (0x02019BC8 + COREINIT_OFFSET) +DC_FLUSHRANGE equ (0x02007B88 + COREINIT_OFFSET) +IC_INVALIDATERANGE equ (0x02007CB0 + COREINIT_OFFSET) +SYS_LAUNCHSETTINGS equ (0x03B9B25C) +_EXIT equ (0x0229a240 + RPX_OFFSET) +exit equ (0x022924b0 + RPX_OFFSET) + +OSFATAL equ (0x02015218 + COREINIT_OFFSET) + +CODEGEN_ADR equ 0x01800000 + +NERD_THREADOBJECT equ (0x107968AC - 0x1000) + +.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 + + + + + +.create "haxchi_rop_hook.bin", 0x107968AC +.arm.big + +rop_hook_start: + + set_sp (rop_start - 4) + +.Close + + + + +.create "haxchi_rop.bin", (0xF4000000 + 0xFD2000) +.arm.big + +rop_start: + + ; call_func HACHI_APPLICATION_SHUTDOWNANDDESTROY, HACHI_APPLICATION_PTR, 0, 0, 0 + + ; call_func SYS_LAUNCHSETTINGS, 0, 0, 0, 0 + ; call_func exit, 0, 0, 0, 0 + ; call_func _EXIT, 0, 0, 0, 0 + ; .word _EXIT + ; .word _START_EXIT + ; .word 0xDEADBABE ; garbage + ; .word 0xDEADBABE ; garbage + ; .word 0xDEADBABE ; garbage + ; .word 0xDEADBABE ; garbage + ; .word 0xDEADBABE ; garbage + call_func_6args NERD_CREATETHREAD, NERD_THREADOBJECT, LWZ_R0x2054_MTLR_R0_ADDI_R1x2050_BLR, 0xDEAD0DAD, thread_param, 0x0, 0x0 + call_func OS_GETTHREADAFFINITY, NERD_THREADOBJECT, 0, 0, 0 + call_func MEMCPY, CORE0_ROPSTART, core0rop, core0rop_end - core0rop, 0x0 + call_func NERD_STARTTHREAD, NERD_THREADOBJECT, 0x0, 0x0, 0x0 + call_func BCTRL, 0x0, 0x0, 0x0, 0x0 ; infinite loop + + core0rop: + ; switch codegen to RW + call_func OSCODEGEN_SWITCHSECMODE, 0x0, 0x0, 0x0, 0x0 + + ; memcpy code + call_func MEMCPY, CODEGEN_ADR, code, code_end - code, 0x0 + call_func DC_FLUSHRANGE, CODEGEN_ADR, code_end - code, 0x0, 0x0 + + ; switch codegen to RX + call_func OSCODEGEN_SWITCHSECMODE, 0x1, 0x0, 0x0, 0x0 + call_func IC_INVALIDATERANGE, CODEGEN_ADR, code_end - code, 0x0, 0x0 + + .word CODEGEN_ADR + core0rop_end: + + output_string: + .ascii "haxthread" + .byte 0x00 + .align 0x4 + + thread_param: + .word output_string + .word 0x00800000 ; stack size + .word 0x00000010 ; thread prio + .halfword 0x0001 ; thread affinity (core0) + + code: + .incbin "haxchi_code/haxchi_code.bin" + code_end: + +.Close