gdbstub_plugin/src/patches.cpp

57 lines
1.9 KiB
C++
Raw Normal View History

2018-09-24 10:43:20 +02:00
#include "cafe/coreinit.h"
#include "kernel.h"
#include <cstdint>
int OSSetExceptionCallback_Patch() {
2022-02-08 14:44:53 +01:00
return 0;
2018-09-24 10:43:20 +02:00
}
int OSSetExceptionCallbackEx_Patch() {
2022-02-08 14:44:53 +01:00
return 0;
2018-09-24 10:43:20 +02:00
}
bool OSIsDebuggerInitialized_Patch() {
2022-02-08 14:44:53 +01:00
return true;
2018-09-24 10:43:20 +02:00
}
void Patch(void *funcPtr, void *patchPtr) {
2022-02-08 14:44:53 +01:00
OSDynLoad_NotifyData *sectionInfo = MainRPL->notifyData;
uint32_t func = (uint32_t) funcPtr;
uint32_t patch = (uint32_t) patchPtr;
if (func < 0x01800000) { //OS function (with trampoline)
for (uint32_t addr = sectionInfo->textAddr; addr < 0x10000000; addr += 4) {
uint32_t *instrs = (uint32_t *) addr;
if (instrs[0] == (0x3D600000 | (func >> 16)) && //lis r11, func@h
instrs[1] == (0x616B0000 | (func & 0xFFFF)) && //ori r11, r11, func@l
instrs[2] == 0x7D6903A6 && //mtctr r11
instrs[3] == 0x4E800420) //bctr
{
KernelWriteU32(addr, 0x3D600000 | (patch >> 16)); //lis r11, patch@h
KernelWriteU32(addr + 4, 0x616B0000 | (patch & 0xFFFF)); //ori r11, r11, patch@l
}
}
} else { //Dynamic function
for (uint32_t addr = sectionInfo->textAddr; addr < 0x10000000; addr += 4) {
uint32_t instr = *(uint32_t *) addr;
if ((instr & 0xFC000002) == 0x48000000) { //b or bl
if ((instr & 0x03FFFFFC) == func - addr) {
instr = instr & ~0x03FFFFFC;
instr |= patch;
instr |= 2; //Turn b/bl into ba/bla
KernelWriteU32(addr, instr);
}
}
}
}
2018-09-24 10:43:20 +02:00
}
void ApplyPatches() {
2022-02-08 14:44:53 +01:00
Patch((void *) OSSetExceptionCallback, (void *) OSSetExceptionCallback_Patch);
Patch((void *) OSSetExceptionCallbackEx, (void *) OSSetExceptionCallbackEx_Patch);
Patch((void *) OSIsDebuggerInitialized, (void *) OSIsDebuggerInitialized_Patch);
2018-09-24 10:43:20 +02:00
}