mirror of
https://github.com/wiiu-env/HBLInstallerWrapper.git
synced 2024-11-22 05:59:15 +01:00
Install the sd_loader directly to have a bit more control
This commit is contained in:
parent
db5adae785
commit
46fd3c52c6
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "homebrew_launcher_installer"]
|
[submodule "homebrew_launcher_installer"]
|
||||||
path = homebrew_launcher_installer
|
path = homebrew_launcher_installer
|
||||||
url = https://github.com/wiiu-env/homebrew_launcher_installer
|
url = git@github.com:wiiu-env/homebrew_launcher_installer.git
|
||||||
|
20
Makefile
20
Makefile
@ -33,8 +33,8 @@ CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__
|
|||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -std=c++20
|
CXXFLAGS := $(CFLAGS) -std=c++20
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH) -mregnames
|
||||||
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS := -lwut -lz
|
LIBS := -lwut -lz
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ endif
|
|||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC) payload.elf.o
|
export OFILES := $(OFILES_BIN) $(OFILES_SRC) sd_loader.elf.o
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||||
|
|
||||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
@ -96,13 +96,13 @@ all: $(BUILD)
|
|||||||
|
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
make -C homebrew_launcher_installer
|
make -C homebrew_launcher_installer/sd_loader
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
make clean -C homebrew_launcher_installer
|
make clean -C homebrew_launcher_installer/sd_loader
|
||||||
@rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf
|
@rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -115,23 +115,23 @@ DEPENDS := $(OFILES:.o=.d)
|
|||||||
# main targets
|
# main targets
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
hbl_installer_payload := ../homebrew_launcher_installer/payload.elf
|
sd_loader := ../homebrew_launcher_installer/sd_loader/sd_loader.elf
|
||||||
|
|
||||||
all : $(OUTPUT).rpx
|
all : $(OUTPUT).rpx
|
||||||
|
|
||||||
$(hbl_installer_payload):
|
$(sd_loader):
|
||||||
make -C ../homebrew_launcher_installer
|
make -C ../homebrew_launcher_installer/sd_loader
|
||||||
|
|
||||||
$(OUTPUT).rpx : $(OUTPUT).elf
|
$(OUTPUT).rpx : $(OUTPUT).elf
|
||||||
$(OUTPUT).elf : $(OFILES)
|
$(OUTPUT).elf : $(OFILES)
|
||||||
$(OFILES) : hbl_installer_payload.h
|
$(OFILES) : sd_loader.h
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
$(OFILES_SRC) : $(HFILES_BIN)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# you need a rule like this for each extension you use as binary data
|
# you need a rule like this for each extension you use as binary data
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
hbl_installer_payload.h: $(hbl_installer_payload)
|
sd_loader.h: $(sd_loader)
|
||||||
@bin2s -a 32 -H `(echo $(<F) | tr . _)`.h $< | $(AS) -o $(<F).o
|
@bin2s -a 32 -H `(echo $(<F) | tr . _)`.h $< | $(AS) -o $(<F).o
|
||||||
@echo '#pragma once' > $@
|
@echo '#pragma once' > $@
|
||||||
@printf '#include "' >> $@
|
@printf '#include "' >> $@
|
||||||
|
197
source/hbl_install.cpp
Normal file
197
source/hbl_install.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <coreinit/dynload.h>
|
||||||
|
#include <coreinit/debug.h>
|
||||||
|
#include <coreinit/memorymap.h>
|
||||||
|
#include <coreinit/cache.h>
|
||||||
|
#include "../homebrew_launcher_installer/sd_loader/src/common.h"
|
||||||
|
#include "../homebrew_launcher_installer/sd_loader/src/elf_abi.h"
|
||||||
|
#include "sd_loader_elf.h"
|
||||||
|
|
||||||
|
#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 address_LiWaitIopComplete 0x01010180
|
||||||
|
#define address_LiWaitIopCompleteWithInterrupts 0x0101006C
|
||||||
|
#define address_LiWaitOneChunk 0x0100080C
|
||||||
|
#define address_PrepareTitle_hook 0xFFF184E4
|
||||||
|
#define address_sgIsLoadingBuffer 0xEFE19E80
|
||||||
|
#define address_gDynloadInitialized 0xEFE13DBC
|
||||||
|
|
||||||
|
#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040
|
||||||
|
#define ADDRESS_main_entry_hook 0x0101c56c
|
||||||
|
|
||||||
|
/* assembly functions */
|
||||||
|
extern "C" void Syscall_0x36(void);
|
||||||
|
extern "C" void KernelPatches(void);
|
||||||
|
extern "C" void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||||
|
extern "C" void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||||
|
|
||||||
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
|
||||||
|
|
||||||
|
static void InstallPatches();
|
||||||
|
|
||||||
|
static unsigned int load_elf_image(const uint8_t *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)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!phdrs[i].p_filesz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned int p_paddr = phdrs[i].p_paddr;
|
||||||
|
image = (unsigned char *) (elfstart + phdrs[i].p_offset);
|
||||||
|
|
||||||
|
memcpy((void *) p_paddr, image, phdrs[i].p_filesz);
|
||||||
|
DCFlushRange((void *) p_paddr, phdrs[i].p_filesz);
|
||||||
|
|
||||||
|
if (phdrs[i].p_flags & PF_X)
|
||||||
|
ICInvalidateRange((void *) 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') {
|
||||||
|
memset((void *) shdr[i].sh_addr, 0, shdr[i].sh_size);
|
||||||
|
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') {
|
||||||
|
memset((void *) shdr[i].sh_addr, 0, shdr[i].sh_size);
|
||||||
|
DCFlushRange((void *) shdr[i].sh_addr, shdr[i].sh_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ehdr->e_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelWriteU32(uint32_t addr, uint32_t value) {
|
||||||
|
ICInvalidateRange(&value, 4);
|
||||||
|
DCFlushRange(&value, 4);
|
||||||
|
|
||||||
|
uint32_t dst = (uint32_t) OSEffectiveToPhysical((uint32_t) addr);
|
||||||
|
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value);
|
||||||
|
|
||||||
|
SC_0x25_KernelCopyData(dst, src, 4);
|
||||||
|
|
||||||
|
DCFlushRange((void *) addr, 4);
|
||||||
|
ICInvalidateRange((void *) addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallHBL() {
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData);
|
||||||
|
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||||
|
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches);
|
||||||
|
|
||||||
|
Syscall_0x36();
|
||||||
|
|
||||||
|
InstallPatches();
|
||||||
|
|
||||||
|
unsigned char *pElfBuffer = (unsigned char *) sd_loader_elf; // use this address as temporary to load the elf
|
||||||
|
unsigned int mainEntryPoint = load_elf_image(pElfBuffer);
|
||||||
|
|
||||||
|
if (mainEntryPoint == 0) {
|
||||||
|
OSFatal("failed to load elf");
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Install our entry point hook
|
||||||
|
unsigned int repl_addr = ADDRESS_main_entry_hook;
|
||||||
|
unsigned int jump_addr = mainEntryPoint & 0x03fffffc;
|
||||||
|
|
||||||
|
unsigned int bufferU32 = 0x48000003 | jump_addr;
|
||||||
|
KernelWriteU32(repl_addr, bufferU32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ****************************************************************** */
|
||||||
|
/* INSTALL PATCHES */
|
||||||
|
/* All OS specific stuff is done here */
|
||||||
|
/* ****************************************************************** */
|
||||||
|
static void InstallPatches() {
|
||||||
|
OsSpecifics osSpecificFunctions;
|
||||||
|
memset(&osSpecificFunctions, 0, sizeof(OsSpecifics));
|
||||||
|
|
||||||
|
unsigned int bufferU32;
|
||||||
|
/* Pre-setup a few options to defined values */
|
||||||
|
bufferU32 = 550;
|
||||||
|
memcpy((void *) &OS_FIRMWARE, &bufferU32, sizeof(bufferU32));
|
||||||
|
bufferU32 = 0xDEADC0DE;
|
||||||
|
memcpy((void *) &MAIN_ENTRY_ADDR, &bufferU32, sizeof(bufferU32));
|
||||||
|
memcpy((void *) &ELF_DATA_ADDR, &bufferU32, sizeof(bufferU32));
|
||||||
|
bufferU32 = 0;
|
||||||
|
memcpy((void *) &ELF_DATA_SIZE, &bufferU32, sizeof(bufferU32));
|
||||||
|
memcpy((void *) &HBL_CHANNEL, &bufferU32, sizeof(bufferU32));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
osSpecificFunctions.LiWaitIopComplete = (int (*)(int, int *)) address_LiWaitIopComplete;
|
||||||
|
osSpecificFunctions.LiWaitIopCompleteWithInterrupts = (int (*)(int, int *)) address_LiWaitIopCompleteWithInterrupts;
|
||||||
|
osSpecificFunctions.addr_LiWaitOneChunk = address_LiWaitOneChunk;
|
||||||
|
osSpecificFunctions.addr_PrepareTitle_hook = address_PrepareTitle_hook;
|
||||||
|
osSpecificFunctions.addr_sgIsLoadingBuffer = address_sgIsLoadingBuffer;
|
||||||
|
osSpecificFunctions.addr_gDynloadInitialized = address_gDynloadInitialized;
|
||||||
|
osSpecificFunctions.orig_LiWaitOneChunkInstr = *(unsigned int *) address_LiWaitOneChunk;
|
||||||
|
|
||||||
|
//! pointer to main entry point of a title
|
||||||
|
osSpecificFunctions.addr_OSTitle_main_entry = ADDRESS_OSTitle_main_entry_ptr;
|
||||||
|
|
||||||
|
memcpy((void *) OS_SPECIFICS, &osSpecificFunctions, sizeof(OsSpecifics));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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"
|
||||||
|
);
|
||||||
|
}
|
3
source/hbl_install.h
Normal file
3
source/hbl_install.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void InstallHBL();
|
74
source/kernel_defs.h
Normal file
74
source/kernel_defs.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef __KERNEL_DEFS_H_
|
||||||
|
#define __KERNEL_DEFS_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// original structure in the kernel that is originally 0x1270 long
|
||||||
|
typedef struct {
|
||||||
|
uint32_t version_cos_xml; // version tag from cos.xml
|
||||||
|
uint64_t os_version; // os_version from app.xml
|
||||||
|
uint64_t title_id; // title_id tag from app.xml
|
||||||
|
uint32_t app_type; // app_type tag from app.xml
|
||||||
|
uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure)
|
||||||
|
char rpx_name[0x1000]; // rpx name from cos.xml
|
||||||
|
uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?)
|
||||||
|
uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2
|
||||||
|
uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app
|
||||||
|
uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?)
|
||||||
|
uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?)
|
||||||
|
uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?)
|
||||||
|
uint32_t max_codesize; // max_codesize in cos.xml
|
||||||
|
uint32_t overlay_arena; // overlay_arena in cos.xml
|
||||||
|
uint32_t unknown4[59]; // all zeros it seems
|
||||||
|
uint32_t default_stack0_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t default_stack1_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t default_stack2_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t default_redzone0_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t default_redzone1_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t default_redzone2_size; // not sure because always 0 but very likely
|
||||||
|
uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker
|
||||||
|
uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker
|
||||||
|
uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker
|
||||||
|
uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker
|
||||||
|
uint32_t title_version; // from app.xml, 0x32 on mii maker
|
||||||
|
/*
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// the next part might be changing from title to title?! I don't think its important but nice to know maybe....
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
char mlc[4]; // string "mlc" on mii maker and sysmenu
|
||||||
|
uint32_t unknown5[7]; // all zeros on mii maker and sysmenu
|
||||||
|
uint32_t unknown6_one; // 0x01 on mii maker and sysmenu
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
char ACP[4]; // string "ACP" on mii maker and sysmenu
|
||||||
|
uint32_t unknown7[15]; // all zeros on mii maker and sysmenu
|
||||||
|
uint32_t unknown8_5; // 0x05 on mii maker and sysmenu
|
||||||
|
uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu
|
||||||
|
uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
char UVD[4]; // string "UVD" on mii maker and sysmenu
|
||||||
|
uint32_t unknown11[15]; // all zeros on mii maker and sysmenu
|
||||||
|
uint32_t unknown12_5; // 0x05 on mii maker and sysmenu
|
||||||
|
uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu
|
||||||
|
uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
char SND[4]; // string "SND" on mii maker and sysmenu
|
||||||
|
uint32_t unknown15[15]; // all zeros on mii maker and sysmenu
|
||||||
|
uint32_t unknown16_5; // 0x05 on mii maker and sysmenu
|
||||||
|
uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu
|
||||||
|
uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu
|
||||||
|
*/
|
||||||
|
// after that only zeros follow
|
||||||
|
} __attribute__((packed)) CosAppXmlInfo;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __KERNEL_DEFS_H_
|
211
source/kernel_patches.s
Normal file
211
source/kernel_patches.s
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
#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
|
||||||
|
|
||||||
|
#define BAT_SETUP_HOOK_ENTRY 0x00800000
|
||||||
|
|
||||||
|
|
||||||
|
#define BAT4U_VAL 0x008000FF
|
||||||
|
#define BAT4L_VAL 0x30800012
|
||||||
|
|
||||||
|
|
||||||
|
#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 Syscall_0x36
|
||||||
|
Syscall_0x36:
|
||||||
|
li r0, 0x3600
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
|
||||||
|
|
||||||
|
.global SCKernelCopyData
|
||||||
|
SCKernelCopyData:
|
||||||
|
// Disable data address translation
|
||||||
|
mfmsr %r6
|
||||||
|
li %r7, 0x10
|
||||||
|
andc %r6, %r6, %r7
|
||||||
|
mtmsr %r6
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
addi %r3, %r3, -1
|
||||||
|
addi %r4, %r4, -1
|
||||||
|
mtctr %r5
|
||||||
|
SCKernelCopyData_loop:
|
||||||
|
lbzu %r5, 1(%r4)
|
||||||
|
stbu %r5, 1(%r3)
|
||||||
|
bdnz SCKernelCopyData_loop
|
||||||
|
|
||||||
|
// Enable data address translation
|
||||||
|
ori %r6, %r6, 0x10
|
||||||
|
mtmsr %r6
|
||||||
|
blr
|
||||||
|
|
||||||
|
.global SC_0x25_KernelCopyData
|
||||||
|
SC_0x25_KernelCopyData:
|
||||||
|
li %r0, 0x2500
|
||||||
|
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
|
||||||
|
|
@ -1,69 +1,7 @@
|
|||||||
#include <string.h>
|
#include "hbl_install.h"
|
||||||
#include <coreinit/title.h>
|
|
||||||
#include <sysapp/title.h>
|
|
||||||
#include <sysapp/launch.h>
|
|
||||||
#include <coreinit/ios.h>
|
|
||||||
#include <coreinit/cache.h>
|
|
||||||
#include "../homebrew_launcher_installer/src/elf_abi.h"
|
|
||||||
#include "payload_elf.h"
|
|
||||||
|
|
||||||
static unsigned int load_elf_image (const uint8_t* 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)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!phdrs[i].p_filesz)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
unsigned int p_paddr = phdrs[i].p_paddr;
|
|
||||||
image = (unsigned char *) (elfstart + phdrs[i].p_offset);
|
|
||||||
|
|
||||||
memcpy ((void *) p_paddr, image, phdrs[i].p_filesz);
|
|
||||||
DCFlushRange((void*)p_paddr, phdrs[i].p_filesz);
|
|
||||||
|
|
||||||
if(phdrs[i].p_flags & PF_X)
|
|
||||||
ICInvalidateRange ((void *) 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') {
|
|
||||||
memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size);
|
|
||||||
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') {
|
|
||||||
memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size);
|
|
||||||
DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ehdr->e_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
uint32_t res = load_elf_image(payload_elf);
|
InstallHBL();
|
||||||
if(res != 0) {
|
|
||||||
((int (*)(int, char **)) res)(0, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user