From acc4c6cdbf6666b7a5a582064e4373397a6c16c7 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 27 Apr 2020 18:35:24 +0200 Subject: [PATCH] Copy BAT hook to the end of our memory area --- src/kernel.cpp | 24 +++++++++++++++-- src/kernel.h | 3 ++- src/kernel_asm_other.S | 60 ++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 4 +-- 4 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 src/kernel_asm_other.S diff --git a/src/kernel.cpp b/src/kernel.cpp index f9d703e..2c2f32a 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -1,13 +1,19 @@ #include +#include +#include +#include + #include "kernel.h" /* assembly functions */ extern "C" void Syscall_0x36(void); extern "C" void KernelPatches(void); +extern "C" void KernelPatchesFinal(void); +extern "C" void SaveAndResetDataBATs_And_SRs_hook(void); void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); -void doKernelSetup(){ +void doKernelSetup() { 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); @@ -17,6 +23,20 @@ void doKernelSetup(){ Syscall_0x36(); } +void doKernelSetup2() { + memcpy((void*)0x00FFF000, (void*)SaveAndResetDataBATs_And_SRs_hook, 0x1000); + ICInvalidateRange((void*)0x00FFF000, 0x1000); + DCFlushRange((void*)0x00FFF000, 0x1000); + + kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int)KernelPatchesFinal); + kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int)KernelPatchesFinal); + kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int)KernelPatchesFinal); + kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int)KernelPatchesFinal); + kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int)KernelPatchesFinal); + + Syscall_0x36(); +} + /* Write a 32-bit word with kernel permissions */ void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { asm volatile ( @@ -37,4 +57,4 @@ void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ); -} \ No newline at end of file +} diff --git a/src/kernel.h b/src/kernel.h index 0c62312..90a317f 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -7,4 +7,5 @@ #define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) -void doKernelSetup(); \ No newline at end of file +void doKernelSetup(); +void doKernelSetup2(); diff --git a/src/kernel_asm_other.S b/src/kernel_asm_other.S new file mode 100644 index 0000000..0d6e16b --- /dev/null +++ b/src/kernel_asm_other.S @@ -0,0 +1,60 @@ +#define BAT_SETUP_HOOK_ADDR 0xFFF1D624 + +#define BAT_SETUP_HOOK_ENTRY 0x00FFF000 + + .globl KernelPatchesFinal +KernelPatchesFinal: + # 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 + + 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 + 0x40) & ~31)@h + ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x40) & ~31)@l + dcbf 0, r3 + icbi 0, r3 + sync + + # 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/src/main.cpp b/src/main.cpp index 0da1781..7e572ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ bool CheckRunning() { extern "C" int _start(int argc, char **argv) { doKernelSetup(); InitFunctionPointers(); + doKernelSetup2(); socket_lib_init(); log_init(); @@ -55,7 +56,6 @@ extern "C" int _start(int argc, char **argv) { uint32_t ApplicationMemoryEnd; asm volatile("lis %0, __CODE_END@h; ori %0, %0, __CODE_END@l" : "=r" (ApplicationMemoryEnd)); - ModuleData * moduleData = ModuleDataFactory::load("sd:/wiiu/payload.rpx", ApplicationMemoryEnd, 0x01000000 - ApplicationMemoryEnd, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); ApplicationMemoryEnd = (ApplicationMemoryEnd + 0x100) & 0xFFFFFF00; @@ -64,6 +64,7 @@ extern "C" int _start(int argc, char **argv) { uint32_t moduleDataStartAddress = ((uint32_t) gModuleData + sizeof(module_information_t)); moduleDataStartAddress = (moduleDataStartAddress + 0x10000) & 0xFFFF0000; + ModuleData * moduleData = ModuleDataFactory::load("sd:/wiiu/payload.rpx", ApplicationMemoryEnd, 0x00FFF000 - ApplicationMemoryEnd, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); if(moduleData != NULL) { DEBUG_FUNCTION_LINE("Loaded module data\n"); std::vector relocData = moduleData->getRelocationDataList(); @@ -103,7 +104,6 @@ extern "C" int _start(int argc, char **argv) { return 0; } - bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { for (auto const& curReloc : relocData) { RelocationData * cur = curReloc;