From 46fd3c52c64315ae64a609d531304245e34d70aa Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 27 Dec 2021 16:53:04 +0100 Subject: [PATCH] Install the sd_loader directly to have a bit more control --- .gitmodules | 2 +- Makefile | 20 ++-- source/hbl_install.cpp | 197 +++++++++++++++++++++++++++++++++++++ source/hbl_install.h | 3 + source/kernel_defs.h | 74 ++++++++++++++ source/kernel_patches.s | 211 ++++++++++++++++++++++++++++++++++++++++ source/main.cpp | 66 +------------ 7 files changed, 498 insertions(+), 75 deletions(-) create mode 100644 source/hbl_install.cpp create mode 100644 source/hbl_install.h create mode 100644 source/kernel_defs.h create mode 100644 source/kernel_patches.s diff --git a/.gitmodules b/.gitmodules index fff8062..9f4aec8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "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 diff --git a/Makefile b/Makefile index 4a17a6e..ef7c35c 100644 --- a/Makefile +++ b/Makefile @@ -33,8 +33,8 @@ CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ CXXFLAGS := $(CFLAGS) -std=c++20 -ASFLAGS := -g $(ARCH) -LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) +ASFLAGS := -g $(ARCH) -mregnames +LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map) LIBS := -lwut -lz @@ -80,7 +80,7 @@ endif export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 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 INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ @@ -96,13 +96,13 @@ all: $(BUILD) $(BUILD): @[ -d $@ ] || mkdir -p $@ - make -C homebrew_launcher_installer + make -C homebrew_launcher_installer/sd_loader @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile #------------------------------------------------------------------------------- clean: @echo clean ... - make clean -C homebrew_launcher_installer + make clean -C homebrew_launcher_installer/sd_loader @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf #------------------------------------------------------------------------------- @@ -115,23 +115,23 @@ DEPENDS := $(OFILES:.o=.d) # main targets #------------------------------------------------------------------------------- -hbl_installer_payload := ../homebrew_launcher_installer/payload.elf +sd_loader := ../homebrew_launcher_installer/sd_loader/sd_loader.elf all : $(OUTPUT).rpx -$(hbl_installer_payload): - make -C ../homebrew_launcher_installer +$(sd_loader): + make -C ../homebrew_launcher_installer/sd_loader $(OUTPUT).rpx : $(OUTPUT).elf $(OUTPUT).elf : $(OFILES) -$(OFILES) : hbl_installer_payload.h +$(OFILES) : sd_loader.h $(OFILES_SRC) : $(HFILES_BIN) #------------------------------------------------------------------------------- # 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 $( $@ @printf '#include "' >> $@ diff --git a/source/hbl_install.cpp b/source/hbl_install.cpp new file mode 100644 index 0000000..8b2e1d5 --- /dev/null +++ b/source/hbl_install.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#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" + ); +} diff --git a/source/hbl_install.h b/source/hbl_install.h new file mode 100644 index 0000000..de72194 --- /dev/null +++ b/source/hbl_install.h @@ -0,0 +1,3 @@ +#pragma once + +void InstallHBL(); \ No newline at end of file diff --git a/source/kernel_defs.h b/source/kernel_defs.h new file mode 100644 index 0000000..efbf04a --- /dev/null +++ b/source/kernel_defs.h @@ -0,0 +1,74 @@ +#ifndef __KERNEL_DEFS_H_ +#define __KERNEL_DEFS_H_ + +#include + +#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_ diff --git a/source/kernel_patches.s b/source/kernel_patches.s new file mode 100644 index 0000000..90187cb --- /dev/null +++ b/source/kernel_patches.s @@ -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 + diff --git a/source/main.cpp b/source/main.cpp index fb57fc4..533e06d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,69 +1,7 @@ -#include -#include -#include -#include -#include -#include -#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; -} +#include "hbl_install.h" int main(int argc, char **argv) { - uint32_t res = load_elf_image(payload_elf); - if(res != 0) { - ((int (*)(int, char **)) res)(0, nullptr); - } + InstallHBL(); return 0; }