diff --git a/source/common/replacement_defines.h b/source/common/replacement_defines.h index c2b2956..1578e9b 100644 --- a/source/common/replacement_defines.h +++ b/source/common/replacement_defines.h @@ -3,7 +3,7 @@ #include #include -#define FUNCTION_PATCHER_METHOD_STORE_SIZE 13 +#define FUNCTION_PATCHER_METHOD_STORE_SIZE 20 #define MAXIMUM_FUNCTION_NAME_LENGTH 83 struct replacement_data_function_t { diff --git a/source/main.cpp b/source/main.cpp index 7f92d22..d2493b6 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -43,10 +44,12 @@ int main(int argc, char **argv) { int test() { WHBLogUdpInit(); + uint32_t upid = OSGetUPID(); + if (upid != 2 && upid != 15) { + return 0; + } bool initNeeded = false; if (pluginDataHeap == NULL) { - kernelInitialize(); - DEBUG_FUNCTION_LINE("Kernel init done"); DCFlushRange((void *) 0x00880000, sizeof(module_information_t)); uint32_t endAddress = 0; DEBUG_FUNCTION_LINE("Using %d modules", gModuleData->number_used_modules); diff --git a/source/patcher/function_patcher.cpp b/source/patcher/function_patcher.cpp index 9bef86d..671ae7e 100644 --- a/source/patcher/function_patcher.cpp +++ b/source/patcher/function_patcher.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "function_patcher.h" #include @@ -112,8 +113,8 @@ void new_PatchInvidualMethodHooks(plugin_info_t *plugin_data) { int32_t method_hooks_count = plugin_data->number_used_functions; uint32_t skip_instr = 1; - uint32_t my_instr_len = 6; - uint32_t instr_len = my_instr_len + skip_instr + 6; + uint32_t my_instr_len = 4; + uint32_t instr_len = my_instr_len + skip_instr + 15; uint32_t flush_len = 4 * instr_len; for (int32_t i = 0; i < method_hooks_count; i++) { replacement_data_function_t *function_data = &plugin_data->functions[i]; @@ -203,41 +204,37 @@ void new_PatchInvidualMethodHooks(plugin_info_t *plugin_data) { WHBLogWritef("Error. Can't save %s for restoring!\n", function_data->function_name); } - //adding jump to real function thx @ dimok for the assembler code /* - 90 61 ff e0 stw r3,-32(r1) - 3c 60 12 34 lis r3,4660 - 60 63 56 78 ori r3,r3,22136 - 7c 69 03 a6 mtctr r3 - 80 61 ff e0 lwz r3,-32(r1) - 4e 80 04 20 bctr*/ - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h - space++; - *space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; - + 00808cfc 3d601234 lis r11 ,0x1234 + 00808d00 616b5678 ori r11 ,r11 ,0x5678 + 00808d04 7d6903a6 mtspr CTR ,r11 + 00808d08 4e800420 bctr + */ + uint32_t ptr = (uint32_t)space; + *space = 0x3d600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = 0x4e800420; space++; + // Only use patched function if OSGetUPID is 2 (wii u menu) or 15 (game) uint32_t repl_addr_test = (uint32_t) space; - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((repl_addr) >> 16) & 0x0000FFFF); // lis r3, repl_addr@h - space++; - *space = 0x60630000 | ((repl_addr) & 0x0000ffff); // ori r3, r3, repl_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; + *space = 0x3d600000 | (((uint32_t*) OSGetUPID)[0] & 0x0000FFFF); space++; // lis r11 ,0x0 + *space = 0x816b0000 | (((uint32_t*) OSGetUPID)[1] & 0x0000FFFF); space++; // lwz r11 ,0x0(r11) + *space = 0x2c0b0000 | 0x00000002; space++; // cmpwi r11 ,0x2 + *space = 0x41820000 | 0x00000020; space++; // beq myfunc + *space = 0x2c0b0000 | 0x0000000F; space++; // cmpwi r11 ,0xF + *space = 0x41820000 | 0x00000018; space++; // beq myfunc + *space = 0x3d600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = function_data->restoreInstruction; space++; // + *space = 0x4e800420; space++; // bctr +// myfunc: + *space = 0x3d600000 | (((repl_addr) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((repl_addr) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = 0x4e800420; space++; // bctr + DCFlushRange((void *) (((uint32_t) space) - flush_len), flush_len); ICInvalidateRange((void *) (((uint32_t) space) - flush_len), flush_len); diff --git a/source/utils/function_patcher.h b/source/utils/function_patcher.h index b9046ef..c80a791 100644 --- a/source/utils/function_patcher.h +++ b/source/utils/function_patcher.h @@ -57,7 +57,7 @@ extern "C" { res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \ res my_ ## name(__VA_ARGS__) -#define FUNCTION_PATCHER_METHOD_STORE_SIZE 7 +#define FUNCTION_PATCHER_METHOD_STORE_SIZE 20 typedef struct { const uint32_t replaceAddr; diff --git a/source/utils/function_patcher_.cpp b/source/utils/function_patcher_.cpp index 7dbedb4..8bb9b93 100644 --- a/source/utils/function_patcher_.cpp +++ b/source/utils/function_patcher_.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "kernel/kernel_utils.h" #include "function_patcher.h" @@ -67,8 +68,8 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[], int32_t hook_informa int32_t method_hooks_count = hook_information_size; uint32_t skip_instr = 1; - uint32_t my_instr_len = 6; - uint32_t instr_len = my_instr_len + skip_instr; + uint32_t my_instr_len = 4; + uint32_t instr_len = my_instr_len + skip_instr + 16; uint32_t flush_len = 4 * instr_len; for (int32_t i = 0; i < method_hooks_count; i++) { DEBUG_FUNCTION_LINE_WRITE("Patching %s ...", method_hooks[i].functionName); @@ -113,7 +114,6 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[], int32_t hook_informa *(volatile uint32_t *) (call_addr) = (uint32_t) (space) - CODE_RW_BASE_OFFSET; - uint32_t targetAddr = (uint32_t) space; if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) { targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); @@ -142,31 +142,43 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[], int32_t hook_informa WHBLogWritef("Error. Can't save %s for restoring!\n", method_hooks[i].functionName); } - //adding jump to real function thx @ dimok for the assembler code /* - 90 61 ff e0 stw r3,-32(r1) - 3c 60 12 34 lis r3,4660 - 60 63 56 78 ori r3,r3,22136 - 7c 69 03 a6 mtctr r3 - 80 61 ff e0 lwz r3,-32(r1) - 4e 80 04 20 bctr*/ - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h - space++; - *space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; - DCFlushRange((void *) (space - instr_len), flush_len); - ICInvalidateRange((unsigned char *) (space - instr_len), flush_len); + 00808cfc 3d601234 lis r11 ,0x1234 + 00808d00 616b5678 ori r11 ,r11 ,0x5678 + 00808d04 7d6903a6 mtspr CTR ,r11 + 00808d08 4e800420 bctr + */ + uint32_t ptr = (uint32_t)space; + *space = 0x3d600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = 0x4e800420; space++; + + // Only use patched function if OSGetUPID is 2 (wii u menu) or 15 (game) + uint32_t repl_addr_test = (uint32_t) space; + *space = 0x3d600000 | (((uint32_t*) OSGetUPID)[0] & 0x0000FFFF); space++; // lis r11 ,0x0 + *space = 0x816b0000 | (((uint32_t*) OSGetUPID)[1] & 0x0000FFFF); space++; // lwz r11 ,0x0(r11) + *space = 0x2c0b0000 | 0x00000002; space++; // cmpwi r11 ,0x2 + *space = 0x41820000 | 0x00000020; space++; // beq myfunc + *space = 0x2c0b0000 | 0x0000000F; space++; // cmpwi r11 ,0xF + *space = 0x41820000 | 0x00000018; space++; // beq myfunc + *space = 0x3d600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = method_hooks[i].restoreInstruction; space++; + *space = 0x4e800420; space++; // bctr +// myfunc: + *space = 0x3d600000 | (((repl_addr) >> 16) & 0x0000FFFF); space++; // lis r11 ,0x1234 + *space = 0x616b0000 | ((repl_addr) & 0x0000ffff); space++; // ori r11 ,r11 ,0x5678 + *space = 0x7d6903a6; space++; // mtspr CTR ,r11 + *space = 0x4e800420; space++; // bctr + + DCFlushRange((void *) (((uint32_t) space) - flush_len), flush_len); + ICInvalidateRange((void *) (((uint32_t) space) - flush_len), flush_len); //setting jump back - uint32_t replace_instr = 0x48000002 | (repl_addr & 0x03fffffc); + uint32_t replace_instr = 0x48000002 | (repl_addr_test & 0x03fffffc); + ICInvalidateRange(&replace_instr, 4); DCFlushRange(&replace_instr, 4); KernelCopyData(physical, (uint32_t) OSEffectiveToPhysical((uint32_t) &replace_instr), 4);