Copy BAT hook to the end of our memory area

This commit is contained in:
Maschell 2020-04-27 18:35:24 +02:00
parent 3cd6ff16e7
commit acc4c6cdbf
4 changed files with 86 additions and 5 deletions

View File

@ -1,9 +1,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <coreinit/cache.h>
#include "kernel.h" #include "kernel.h"
/* assembly functions */ /* assembly functions */
extern "C" void Syscall_0x36(void); extern "C" void Syscall_0x36(void);
extern "C" void KernelPatches(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 __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
@ -17,6 +23,20 @@ void doKernelSetup(){
Syscall_0x36(); 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 */ /* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile ( asm volatile (

View File

@ -8,3 +8,4 @@
void doKernelSetup(); void doKernelSetup();
void doKernelSetup2();

60
src/kernel_asm_other.S Normal file
View File

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

View File

@ -44,6 +44,7 @@ bool CheckRunning() {
extern "C" int _start(int argc, char **argv) { extern "C" int _start(int argc, char **argv) {
doKernelSetup(); doKernelSetup();
InitFunctionPointers(); InitFunctionPointers();
doKernelSetup2();
socket_lib_init(); socket_lib_init();
log_init(); log_init();
@ -55,7 +56,6 @@ extern "C" int _start(int argc, char **argv) {
uint32_t ApplicationMemoryEnd; uint32_t ApplicationMemoryEnd;
asm volatile("lis %0, __CODE_END@h; ori %0, %0, __CODE_END@l" : "=r" (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; 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)); uint32_t moduleDataStartAddress = ((uint32_t) gModuleData + sizeof(module_information_t));
moduleDataStartAddress = (moduleDataStartAddress + 0x10000) & 0xFFFF0000; 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) { if(moduleData != NULL) {
DEBUG_FUNCTION_LINE("Loaded module data\n"); DEBUG_FUNCTION_LINE("Loaded module data\n");
std::vector<RelocationData *> relocData = moduleData->getRelocationDataList(); std::vector<RelocationData *> relocData = moduleData->getRelocationDataList();
@ -103,7 +104,6 @@ extern "C" int _start(int argc, char **argv) {
return 0; return 0;
} }
bool doRelocation(std::vector<RelocationData *> &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) { bool doRelocation(std::vector<RelocationData *> &relocData, relocation_trampolin_entry_t * tramp_data, uint32_t tramp_length) {
for (auto const& curReloc : relocData) { for (auto const& curReloc : relocData) {
RelocationData * cur = curReloc; RelocationData * cur = curReloc;